A Mission Stopped When the Lid Closed
Since the first release, a Skyflo mission has been the durable unit of work. It holds one objective, its approved plan, the agents working on it, the record of what they did, and what the work taught. Close the window and the mission is still there. Restart the app and it picks up from its record.
What a mission could not survive was its Mac going to sleep. The agents ran on the Mac, so the work ran only while the Mac did. In 1.3 we let a phone answer a waiting mission, and the support page still had to say it plainly: the Mac must be awake. A migration that needed another forty minutes, a test suite that took an hour, a fix you wanted finished by morning: each one waited on a laptop lid.
Skyflo 1.5 removes that condition. A mission can now run in Skyflo Cloud, on a machine Skyflo operates for it, and keep working while your Mac sleeps, is offline, or is closed in a bag. When it is idle you bring it back, and it continues on your Mac with the work it did there.
This is the largest change to what Skyflo is since it became a HyperAgent. The control plane already decided which agent works on a mission, what it may do and what gets recorded. Now it also carries the mission between your Mac and Skyflo Cloud when you choose to move it, and keeps the same record, the same agent and the same spend limit on either side of the move. While the mission is in Skyflo Cloud, the boundaries of its machine take the place of approval prompts.
What You Do
On a mission, choose Run in Skyflo Cloud. The dialog says what will happen in four lines. What moves: the whole mission, its conversation included, plus your uncommitted changes and unpushed commits. What stays on the Mac: ignored files such as node_modules, untracked credential files such as .env, very large untracked files, and anything the mission was running there, which stops. Its access: Full access in its own machine, returning to the mode it had when it comes back, and on GitHub it can only push its own branch and open a pull request. What it costs: machine time and model use, counted against your plan's allowance, up to the mission's own spend limit.
You can give it an instruction for what to do next, or leave it empty and it waits for you there, for up to 7 days without activity; after that its work is saved in Skyflo Cloud for 30 days and its machine is released. Continue from the conversation so far is a separate choice, off by default. With it on, the agent in Skyflo Cloud reads what came before and picks up where the Mac left off. With it off, it starts fresh from your next message, and the transcript says so. Either way the conversation travels with the mission's record; the choice decides only whether the agent there reads it.
The mission then reads In Skyflo Cloud, and from your Mac it behaves like a local one. The conversation is live, you can send a message into the running turn or start the next one, Stop stops it, and a question it asks waits for your answer. If your Mac goes offline the composer says what is true: the mission keeps working in Skyflo Cloud. Your paired phone reads the same record, so it can follow the mission too.
When the mission is idle, Bring back to this Mac returns it. If it is still working, Skyflo offers to stop that turn first or to wait. If you changed the same repository on the Mac while the mission was away, that work is not overwritten. It is kept separately as Git refs, and the mission tells you so, with one button to copy them.
None of this needs a commit or a push.
A Checkpoint, Not a Branch
The obvious way to move a coding task to another machine is to commit what you have, push a branch, and clone it on the other side. It fails on the state that matters most. Work in progress is rarely committed. It is a staged rename, an unstaged edit, a new script with its executable bit, a symlink, a file the agent created ten minutes ago and has not mentioned yet. Asking a person to commit all of that before a move turns a move into a chore, and asking an agent to do it produces commits nobody wanted.
So a move carries a portable checkpoint instead. When you move a mission, the Mac's daemon records that the mission has departed, and from that moment refuses every write to it. It then writes one checkpoint: the mission's history, and each repository as Git objects, meaning the commit it is on, the staged tree, and a tree of every file in the working copy that the repository does not ignore, with its mode. The repository part is bundled against a commit the remote already has, so only what is new travels. Ignored files, untracked credential files and very large files are named in the checkpoint rather than carried, and the move shows you that list. That screen for credential files looks only at the names of untracked files. Everything the repository tracks, its unpushed history, and the mission's own conversation and tool output travel as they are, so a secret you committed travels with them.
In Skyflo Cloud, the runner downloads the checkpoint, clones the repository, lands the history, restores each working copy and checks that it hashes to exactly what was sealed before it records that the mission has arrived. Coming back is the mirror image.
We tested this on our staging service before release with a deliberately untidy checkout: two unpushed commits, a staged edit and a staged rename, an unstaged edit and a deletion, an untracked executable script and a symlink, an untracked .env, and ignored .venv and __pycache__ folders. Nothing was committed or pushed. The mission moved, did its work in Skyflo Cloud and came back. On the Mac the commit, the branch and the staged tree were unchanged, the only change in the working copy was the one the agent made, the symlink and the executable bit were intact, and .env and .venv were exactly where they had been, because they had never left.
One Owner at a Time
A mission that can be in two places has to be in exactly one of them at any instant. Two machines both believing they own a mission is how work gets written twice or lost.
Skyflo keeps one owner per mission with an epoch: a number that every change of owner increases, held by Skyflo's account service. Every write that matters, a checkpoint chunk, a model request, a push, carries the epoch of the machine making it, and anything carrying an older epoch is refused.
The move is ordered so that there is never a moment without a durable copy. The Mac takes the mission's authority and names the run it will go to. It writes and uploads the checkpoint, each chunk admitted at its epoch, and completes it by re-reading every chunk and checking the digest. Then, in one transaction, the checkpoint is sealed and the run in Skyflo Cloud is given the next epoch. The run therefore never holds the mission before its checkpoint is durable, and from that commit on the Mac's own writes are refused. If anything fails before that transaction, the mission simply stays on the Mac. Everything after it can be repeated safely.
Bringing a mission back follows the same rule in reverse. The Mac asks, the runner hears the request, waits until the mission is quiet, and seals a checkpoint that only that Mac can read or take. One rule took a while to get right: a device never takes a mission from a runner that still holds it, even when the runner's lease has lapsed, because a sleeping runner's lease lapses as a matter of routine. Sleeping is not the same as gone.
On staging we tried to break this on purpose. After recovering a run onto a fresh identity, we replayed the old identity against the same machine. It could no longer authenticate, its final attempt to publish the mission was refused, and it parked itself within a second.
Sleeping Is the Point
A machine that runs a mission does not need to stay awake while the mission waits for you. When a turn ends, the runner lets its machine sleep, and a message for the mission wakes it. On staging, an idle runner stopped seven seconds after its turn finished and was suspended by thirteen, and in another run a sleeping one answered within 581 milliseconds when work arrived.
Sleep shows up in how long things take, and we would rather give you the numbers than an adjective. Measured on our staging service before release, from a Mac:
- Moving a mission to Skyflo Cloud took 10.7 and 12.6 seconds. Most of that is creating the machine it runs on.
- Bringing it back took 5.8 seconds from a machine that was awake.
- Bringing it back from a machine that had gone to sleep took 39.5 and 68.2 seconds. In the first of those runs, 37.7 seconds passed inside the machine before its seal was complete, against 3.6 seconds for an awake one. The machine itself answers within a second of waking, so most of that time goes to the seal after the wake, and we have not yet measured where inside the seal it goes.
Those are staging figures, not a promise about every repository. A larger working copy takes longer to checkpoint, and the Desktop says so while you wait: after ten seconds it explains that Skyflo Cloud saves the mission's work before handing it back.
What the Machine Holds
An agent in Skyflo Cloud does real work: it installs dependencies, runs tests, edits files and runs commands. Inside its machine a mission runs with Full access, whatever mode it had on your Mac, because the machine is the boundary; when it comes back, your Mac returns it to the mode it left with. The machine belongs to that one mission, and the design question was which credentials it should hold. The answer is as few as possible.
No model provider key. Codex and Skyflo's own agent in Skyflo Cloud use Skyflo's managed models, and they reach them through a small proxy inside the machine that holds no provider credential. The proxy carries a grant that lasts fifteen minutes and is bound to that runner, that run, that mission and that epoch, and it signs every request. Skyflo's gateway authorizes, reserves and settles each call exactly as it does for a turn on your Mac, and additionally checks the mission's epoch and its spend limit.
No GitHub credential. The machine cannot reach GitHub directly. Git goes through a Skyflo service outside the machine that holds the GitHub App's key, mints a token narrowed to one repository and one operation, and checks the mission, its epoch and the repository before it acts. Whatever the agent asks for, that service pushes only the mission's own branch and opens only that branch's pull request. It refuses the default branch, every other branch, tags and deletions, a mission there cannot merge, and no approval changes that. GitHub's own branch protection applies on top.
It also refuses any push that would change what GitHub Actions runs: a workflow under .github/workflows, a local action under .github/actions, or an action.yml at the repository's root. A workflow decides which secrets and permissions a job gets, so changing one is a way to reach credentials the mission was never given. The token Skyflo mints for a cloud run has no permission to change workflows, so GitHub would refuse that push too, and Skyflo reads the pushed commit itself before GitHub sees a byte. If the work needs such a change, the agent commits it on the mission's branch and tells you; bring the mission back and push it from your Mac. Workflows your repository already has still run on the mission's branch, as they would for anyone's push, and you can leave skyflo/** branches out of the ones that hold secrets. A mission you started in Skyflo Cloud commits to its own branch, pushes it and opens a pull request for you to review. A mission you moved keeps its own workflow: Skyflo Cloud does not commit or push on its behalf, and its work comes back to your Mac as uncommitted changes, the way it left.
A short list of places it can reach. The machine's network reaches Skyflo's services and public package registries, such as npm, PyPI, crates.io and Maven Central, so a mission can install its project's dependencies and run its tests. Everything else is refused. On staging, a probe from inside a runner reached Skyflo and was refused by example.com, by github.com, by a model provider and by the cloud metadata address. On staging we also scanned 243 MB of a runner's process environments and files for every secret held on our operator Mac, and found none.
What the machine does hold is the mission itself: its record, including the conversation, and its repositories, including anything you committed to them, secrets too. It also holds the credentials that let this one runner speak for this one mission at this one epoch, which are useless once the epoch moves on. We say this plainly because it is the honest boundary: an agent inside the machine can reach that runner credential, and so can any program the mission runs, a dependency's install script included. What any of them can do with it is limited to the mission it is already working on: its managed model calls within its spend limit, and its own branch.
What Skyflo keeps. While a mission runs in Skyflo Cloud, Skyflo holds its content, and the privacy notice lists how long each part is kept, backups included. The checkpoint that carries a mission between your Mac and Skyflo Cloud is deleted once your Mac confirms it has landed the mission, and otherwise after 30 days. Once a mission's work is saved, or it comes home, the machine it ran on is destroyed, and if that fails Skyflo keeps retrying until it succeeds. A machine that holds work nobody has saved yet is never destroyed; the mission tells you its work is still there and you can bring it back.
Your GitHub, Connected Once
Cloud missions need a way to your repositories that does not put a credential on the machine, and that is Skyflo's GitHub App. Connecting it turned out to be useful on its own, so it is not a cloud feature. You can connect GitHub from Skyflo's setup or from Settings on every plan, including Free, and choose all your repositories or selected ones on GitHub's own screen. The App asks to write contents, pull requests and workflows, and to read actions, checks, commit statuses and metadata.
On your Mac, the connection lets Add project list your repositories and clone one without the GitHub CLI, and missions push through it. Each use gets access to one repository that expires within the hour, and Skyflo never asks for a GitHub password or token. If the connection does not cover a repository, Skyflo falls back to your own Git or GitHub CLI sign-in, as before.
What It Costs, and Where It Stops
Skyflo Cloud is included with paid plans. What a mission uses there comes out of the same monthly allowance as your managed model use: the model calls it makes, and its machine time.
Machine time is measured every 30 seconds while the machine is awake, from the processor, memory and storage it actually uses, and each awake hour is held between about 9 cents and 1.33 USD. A sleeping machine costs nothing. A machine stays awake for about thirty seconds after its last activity before it sleeps, and that tail is counted. Once a mission has been asked to stop, the time its machine spends saving the mission is Skyflo's own upkeep and is not charged. The Usage page lists the result as Skyflo Cloud machine time.
Every mission in Skyflo Cloud has a spend limit, and the Desktop shows it as what it has used of that limit. A model call that would cross the limit is refused before it runs and costs nothing. Machine time cannot be refused in advance, because it is measured after the machine has used it, so it is held instead: a charge that would cross the limit is cut to what the limit has left, the rest is waived, and the mission pauses in the same step. A paused mission therefore shows its limit reached, never exceeded.
Pausing means stopping. When a mission reaches its limit, the runner stops what is running, waits until every process the mission started has ended, and then seals the mission's work so nothing is lost. In one staging run we watched from outside the runner: the mission's five background jobs went to zero in 82 milliseconds, and only then was the checkpoint sealed. Raise the limit to continue in Skyflo Cloud, or bring the mission back to your Mac, where your own agents and keys keep working as before. The saved work waits 30 days. An organisation's daily Skyflo Cloud limit stops a mission the same way, and it can continue on a later day.
Billing fails toward you. If Skyflo's own service could not measure a machine for a while, the gap is billed at most 30 seconds, whatever the machine did. On staging we reconciled one mission to the ledger: seven model calls and six machine-time charges added up to the mission's recorded spend to the micro-dollar.
What It Does Not Do Yet
A move is deliberate, and a few things are not in this release:
- A mission moves when it is idle. If it is working, it moves once the turn finishes; if it is waiting on you, you answer it first.
- Codex and Skyflo's own agent run in Skyflo Cloud. Claude Code and other agents stay on your Mac. A mission never switches agents to make a move work; if its agent cannot run in Skyflo Cloud, nothing moves and the dialog says why.
- Repositories reach Skyflo Cloud through the GitHub App, so a mission there works on GitHub repositories.
- Images and files cannot be attached to a message for a mission in Skyflo Cloud yet.
- A change to your GitHub Actions workflows is pushed from your Mac, not from Skyflo Cloud.
- Free keeps everything it had, plus the GitHub connection. Skyflo Cloud needs a paid plan and Skyflo 1.5.1 or later.
Why This Is the Release That Changes the Story
We have described Skyflo as the control plane for agentic engineering: the layer above the agents a team already runs, which decides who works on what, under which authority, and keeps the record. Until 1.5, that layer lived on one Mac, and so did the work.
Now the mission is portable. It carries its history, its uncommitted state and its agent between your Mac and Skyflo Cloud, with one owner at a time and no provider or GitHub credential on the far side. The work keeps going when you close the laptop. The record and the spend limit go with it, and in Skyflo Cloud the machine's boundary takes the place of approval prompts.
In 1.3 we wrote that the phone decides and the Mac acts. With 1.5 the thing that acts can be your Mac or a machine in Skyflo Cloud, and the decisions still come from you.
The 1.5.0 release notes list what shipped, and the pricing page shows what each plan includes.