Skip to content

Updating roamd

roamd on your computers never updates by itself. A new version only goes on when you, signed in with your vault open, connect to a computer and say yes.

The website and installed app

A new web version downloads in the background. When it is ready, the reload icon appears in the hamburger menu on phones and tablets, including installed Apple apps. On desktop it appears at the right of the header. Tap it when you are ready to reload. The app checks when brought back, when connectivity returns, and periodically while open. An offline or failed check can be retried when you return with a working connection. Another open window can activate a downloaded version without reloading your current page; that page keeps its reload offer.

return to app / keep it open -> check -> download ready
phone or tablet -> hamburger menu -> reload icon
desktop         -> header         -> reload icon

You stay in charge

  • Offers are on by default, and an offer is only a question: nothing installs until you say yes. To stop them, untick Account → roamd updates → Offer to update roamd when I connect to a machine. The choice is saved in your encrypted vault, not on the computers, so a computer can't change it.
  • Only when you connect, and only for the computer you're looking at. If a newer roamd is out and the computer you just connected to has an older one, you're asked, with what's new. With several computers open (for instance after a reload), a computer in a tab you aren't looking at waits: it's asked about when you switch to its tab, so you never get one question after another:
 +--------------------------------------------------------------+
 |  roamd 0.3.0 is ready for my-laptop (it has 0.2.0).          |
 |                                                              |
 |  What's new:                                                 |
 |   - Terminal tabs reopen where you left them                 |
 |                                                              |
 |  [ Update now ]  [ Not now ]  [ Don't ask until next version]|
 +--------------------------------------------------------------+
  • Update now: the computer downloads the new roamd, checks it, swaps it in and restarts. Connect again in a moment. If the computer doesn't answer within two minutes (it may have updated and be restarting, and its reply got lost), the dialog says so and you can close it; Open sessions shows the computer's version once it is back. The dialog can be closed at any time while it waits. This is the same on Windows, Mac, Linux and phones. Once the computer is back, an open terminal on it reconnects by itself. Windows computers start roamd again straight away too, as Mac and Linux do.
  • Not now: nothing changes. You aren't asked again for that computer in the same browser tab, but you're asked again next time you open the app and connect.
  • You're asked once per computer: with several terminals open on the same computer, in one tab or in other windows of the same browser, the others don't ask again, and none ask while it is updating.
  • Don't ask until the next version: you aren't asked about this version again, on any browser (it's saved in your vault). A newer version asks again.

Why you can trust an update

 our website            YOUR COMPUTER
 -----------            -------------
 new roamd  ----------> downloads it
 + notes, with a        checks the signature (a seal only roamd's
   seal on them         makers can make) and the checksum
                        |
              seal wrong, or file changed?
                 yes -> refuses, changes nothing
                 no  -> swaps it in, restarts

The seal is made with a key that isn't kept on our website. So even someone who took over the website couldn't send your computers code of their own: they'd fail the check. A computer also refuses anything that isn't newer than what it runs.

If the new roamd doesn't work

roamd keeps the version it replaced beside the new one, and checks the new one before it changes anything.

 download -> checked -> new roamd is run once to see it starts
                              |
                  won't start? -> old one kept, nothing changed
                              |
                  swapped in, restarts
                              |
                  doesn't stay up for a short while?
                     yes -> the old one comes back, by itself
                     no  -> the new one is kept, old one cleared away

This works the same on Windows, Mac and Linux, so Windows computers update from the browser like the others. If the computer is switched off or restarted just after an update, before the new roamd has proven itself, it may go back to the old one: update again when you like. The same happens if the new roamd can't even start (for example it can't read its saved settings): it is started again, and the second try brings the old one back. Asking for a second update while one is waiting to take effect is refused, so the way back is never overwritten.

Limits

  • Only an owner of a computer can update it; people you shared it with can't.
  • A computer whose roamd is older than 0.2.0 can't check seals yet. For those, Update now runs roamd's normal installer on the computer (over the same locked connection) and then restarts roamd there. That installer checks the download against the checksums on our website, like the first install did, but not the seal. From then on, updates are sealed. That step needs a Linux or Mac computer; on an old Windows one, run the PowerShell install command on it instead.
  • If you started roamd run by hand rather than as a service, it stops after updating: start it again.
  • Existing Mac releases may repeat permission questions after updates. They lack a stable Mac signing identity. The release process now requires one so macOS can recognise later versions as the same program. This needs a new signed release and still needs verification on a real Mac. The first switch to the signed identity may ask once more. Signing does not grant access automatically or change your privacy settings. A permission prompt appears on the Mac's screen; the website cannot answer it for you.
first signed Mac version -> you choose folder access
later version, same identity -> macOS can reuse your choice

Web and installed app

The PWA follows an existing installing worker when registration resolves, and subscribes to later updatefound events. Foreground, focus, online and visible periodic checks call registration.update with concurrent requests coalesced; failures release the pending request so a later check can retry. The worker script bypasses HTTP caches. Waiting workers and controller identity are reconciled on resume, including activation events missed during suspension. First control is not an update. Activation by another tab marks this page stale without reloading it; the person's reload action activates a waiting worker and reloads after control changes. An ordinary navigation also permits activation. The icon stays in the phone/tablet drawer or desktop header.

registration -> follow current download + future downloads
visible return / timer -> check -> waiting worker -> reload offer
missed activation      -> changed controller      -> reload offer

Lifecycle/UI checks run in WebKit and Chromium with installed-app state simulated. A real worker release/reload test covers the tablet menu in Chromium; physical installed iPad and iPhone verification remains.

How it works

Part Behaviour
Setting Vault item updates: {offer, skip}. offer defaults to true (an offer is only a question) and is only written by a browser with the vault open. The machine has no setting and no timer: it never contacts the download site for this on its own.
Release manifest Plain text, signed with minisign (Ed25519): version, one file NAME SHA-256 line per build, then notes. The private key is never on the download site; the public key is built into every roamd.
Prompt After the terminal opens, if offer is on, the page reads the newest manifest from the download site, asks the machine which version runs (version), and prompts only if the release is strictly newer and not at or below skip.
Browser reading The page shows the manifest's version and notes for reading only. It does not rely on them: the machine verifies everything.
Request A request on its own encrypted subsystem, over the terminal's SSH connection: version (any trusted key) or apply (owner keys only; guests are refused).
Machine checks Fetches the manifest and its signature and verifies the signature before reading the text; requires the version to be strictly newer (a downgrade or an unreadable number is refused); requires a build for this system whose SHA-256 matches the signed one; then writes the file beside the running one and renames it over (the old file stays whole until the instant the new one is). Nothing changes unless every check passes.
Restart After the answer is sent, the machine exits with a failure status so systemd or launchd starts the new build (a service restarts only after failures). Started by hand, it simply stops.
Skip "Don't ask until the next version" stores the version in the vault; newer versions ask again. Any answer (or none, while the dialog is open) is remembered in the page for that machine, so other terminals on it don't ask again; other windows of the same browser hear of it over a BroadcastChannel. A fresh page asks again.
Old machines A roamd without the subsystem refuses it. If the user says yes, the page runs the official installer on the machine over a short SSH connection of its own (as the owner's key can already run commands there): it replaces the roamd already on the PATH (else the default folder), prints roamd updated., then runs roamd service install, which restarts roamd and ends the connection. The installer verifies the build against the published SHA-256 list only; the signature check exists from 0.2.0 on.
Windows Same steps as everywhere: a running .exe can't be overwritten but can be renamed, so the running file is moved aside and the new one moved in. Task Scheduler's "restart on failure" did not bring roamd back after an update (the task sat Ready with result 0x4B, roamd offline), so the task also has a trigger that repeats every minute and starts roamd if it isn't running (a running one is left alone). A task made by an older roamd is registered again with that trigger the next time roamd starts. That trigger alone left a machine away for up to its interval after each update, so roamd running as the service, as it exits to restart, leaves a hidden PowerShell helper behind (taken out of the task's job where Windows allows): it waits for roamd's process to end and for the task to stop counting as running (a start before then is ignored), then starts the task at once. If the helper can't start, the trigger still brings roamd back. Not yet run against a real Windows update beyond that one report.
Before the swap The new build is written beside the running one (.new) and run once with --version; it must exit successfully saying roamd <the signed version>, within a limit. If not, the file is deleted and nothing changes ("the new version wouldn't start, so the old one was kept").
The swap Remove an earlier .old; rename the running file to .old; rename .new into place. If the last step fails, the old file is renamed back. A marker file (.pending) records that the new build is on trial.
Rollback At each start, a marker means a build on trial: the first start waits for the build to stay up for a short while, then clears the marker and .old. A second start before that (including a start that fails before roamd is up, which a service now retries) restores .old (the new build is kept as .failed, cleared at the next start) and exits with a failure status so the service manager starts the old build.
macOS permissions Existing Intel builds are unsigned and Apple Silicon builds have an ad-hoc signature tied to their code. The release process now requires a Developer ID Application certificate, a stable code identifier and the same Apple Team ID for both architectures, with code signing before checksums. This lets macOS TCC match the designated requirement across updates. The first identity transition may require fresh consent. No privacy database changes or automatic grants are made. A signed release and native permission-continuity testing are still needed; code signing does not itself notarise the download.
Limits of rollback A build that stays up but misbehaves is kept. A build that starts but can't reach the hub is not told apart from a working one.

Flow

Mac builds -> stable Developer ID signature -> checksums
                |
         macOS recognises the signer and app across updates
browser (vault open)                        machine
  |  read newest manifest (notes)             |
  |  ---- version? (encrypted, SSH) --------> |
  |  <--- version 0.2.0 linux-x86_64 -------- |
  |  prompt: Update now / Not now / Skip      |
  |  ---- apply (owner key only) -----------> |
  |                          fetch manifest + signature + build
  |                          verify signature, newer, SHA-256
  |                          run new build once (--version)
  |                          swap file (old kept), answer
  |  <--- updated 0.3.0 --------------------- |
  |                          exit -> service manager restarts
  |                          (Windows: helper waits for the exit,
  |                           then starts the task at once)

The release script (make release) builds, signs and publishes; see the repository's README.