Repository navigation
Releases: MagicZebraLtd/loam
Release list
LOAM 0.7.0
LOAM 0.7.0 — 27 October 2026
The launch release: the desktop app's first release, the assistant through any OpenAI-style chat service,
and the fixes from two independent pre-launch reviews (one external, one internal) of the whole code base.
The Google Play bundle is versionCode 13.
Security
- The Android host keeps no plaintext copy of messages outside its encrypted database. On an encrypted
network the host app's own browser view now tells the web client to keep no local copy (the same
window.__loamHostNoLocalCachethe desktop app has set since it was built) and switches its page cache
off, and the web client deletes the copy an earlier version of the app left behind the first time it
loads. Pictures and files are also served withCache-Control: no-storewhenever the database is
encrypted, so neither host window can cache them on disk. Phones that join a network are unaffected.
Not yet verified on a physical phone (docs/21). - A hardened (Private) network now refuses an Ollama address off the local network (judged by the address
as written, as for a chat service: loopback, private and link-local addresses,.localand dotless names
count as local), as it already
refused an online chat service: the rule covers both backends when a setting is saved, at boot from a
hand-editedconfig.json, and for the admin screens' Test connection. Requests from a hardened network to
its assistant never follow an HTTP redirect either, so a local address can't hand the conversation to a
public one. The admin page and theloamnetSettings screen now say so for an Ollama address too. - People are told where the assistant runs, in the assistant's own chat. The network tells every client
whether replies come from the host's phone, the host's computer, another computer on the local network,
or an online service (NetworkConfig.assistantDestination, named by its hostname); the assistant's
chat shows it under the name, and an online service shows a notice that each device confirms once before
its first message goes out. When the host changes where the assistant runs, the earlier conversation is
not sent along: the assistant's memory of each chat starts again from that change. Before, only the admin
page said where messages went, and switching a local assistant to an online service could send up to 40
earlier turns there with the next message. - The security claims are scoped to what the code does. The transport encryption protects messages from
anyone listening on the Wi-Fi and from a look-alike host at join time; it does not protect a phone from
someone who can rewrite traffic while LOAM's page loads over plain HTTP, since the code that checks the
key is the code being replaced. docs/08, SECURITY.md, the README, the site and both privacy policies now
say so, and the site no longer says--encryptencrypts "everything" (pictures and files are stored
beside the database, unencrypted) or that a Private network "leaves nothing readable" (it throws away the
key to its messages when LOAM stops; pictures and files are deleted the next time it starts). Deleting a
message is removed here and refused on re-import by linked networks, but a copy they already pulled stays
there; the operators' guide said otherwise. - The Android host no longer writes a line per request to the device log. The embedded server's output
goes to logcat, which sits outside the encrypted database and can be read withadbor from a bug report,
and each request line carried a joiner's address and a timestamp. LOAM's own warnings and errors are still
logged; they carry no message text, names or keys. The host app also stops logging the page URL on a load error. - Private channels get an opaque id (
chan_<hex>) instead of one made from their name. A channel's id
lands where a reset can't reach (joiners' browser history, the host window's remembered last conversation,
the plaintext paths of a client that skipped the QR code), so a name-derived id told anyone with that
history that a hidden channel of that name existed. Public channels keep their readable slugs. Existing
private channels keep the id they have. - The panic route takes the same time to answer whether or not a token is configured, so a prober on the
LAN can no longer tell an armed node from a plain one by timing the 404. - The host app's WebView opens links through its own navigation guard (
setSupportMultipleWindowsoff,
so atarget=_blanklink can't be handed to a detached popup) and no longer asks for third-party cookies. - Electron 44.9.1 in the desktop app, which carries the mitigation for the compromised eMudhra
intermediate certificates (GHSA-jr5w-w6x2-84p9). - Security reporting: GitHub private vulnerability reporting is enabled for the repository and named in
SECURITY.md, whose scope now lists the Android, desktop and terminal host apps. - Third-party licence notices ship with every build. A generator (
scripts/third-party-notices.mjs) writes
the bundled open-source packages and their licence texts intoTHIRD_PARTY_NOTICES.txtbeside theloamnet
server bundle, the desktop app's and the Android host's, and the web client serves its own at
/third-party-notices.txt, linked from Settings. Nothing is downloaded or committed; the files are made at
build time (docs/14 "Licence notices").
Added
- The assistant can answer through an online or local chat service, not only Ollama: OpenRouter,
OpenAI, Groq, Mistral, LM Studio, llama.cpp server, or any other service with an OpenAI-style API. Admins
pick where the assistant runs (off, Ollama, a chat service, or on the Android phone), choose a service by
name, paste its key (kept on the host and never shown again, not even to admins), press Test connection
to pick a model from the service's list, and are told plainly when messages to the assistant will leave
the network. The same settings are in theloamnetSettings screen; the desktop app's Settings and the
Android host's AI assistant screen open them. A hardened network only accepts a service on this computer
or the local network. Off by default; nothing changes for a network that doesn't turn it on. - A desktop app for Mac, Windows and Linux (
apps/desktop, Electron). Open it, answer a few questions,
and it shows the code people nearby scan to join; you are the network's admin, and closing the window keeps
the network running until you quit. It has the same screens as the phone host (the code, display mode,
linking another LOAM node, people, activity, settings, Emergency Reset) and keeps its network's key in the
computer's keychain, or behind a passphrase, or only in memory. Installers:LOAM-mac-arm64.dmg,
LOAM-mac-x64.dmg,LOAM-win-x64.exe,LOAM-linux-x64.AppImageandLOAM-linux-x64.deb, each with a
checksum and a signed build record on the release. It never checks for updates by itself and sends nothing
anywhere. The Mac builds are signed by Magic Zebra Limited and notarized by Apple, so they open with no
"Open Anyway" step; the Windows installer is not yet signed (SignPath Foundation is the plan), and the
Windows and Linux builds have not yet been run on real machines. This is its first release. See
docs/24-electron-desktop.md. - A website page for the desktop app (
/desktop) and the code signing policy (/code-signing).
Changed
- The web client runs on Preact 11 (from 10.29). Refs now start explicitly empty, and the crash screen's alert
role moved onto its card so the page keeps itsmainlandmark.preact-render-to-stringis pinned to 6.8, which
Preact 11 needs. - The first-run setup choices (Private, Community, Choose every setting myself) now live in
@loam/schema, so the Android app and the desktop app set up a network from the same code and cannot
drift apart. Nothing changes for the phone. - The server bundle recipe is shared:
scripts/lib/bundle-server.mjsis used by both theloamnet
package build and the desktop app. Theloamnetoutput is unchanged. - Stopping the node no longer waits for a request that never finishes. The embedded server (the desktop
app, the Android host,loamneton Ctrl-C) closes its connections when it shuts down instead of waiting
for every in-flight request, so a stalled upload can't hold a stop open for ever. - The web client keeps no local copy when the host app says not to (
window.__loamHostNoLocalCache):
the desktop app sets it on every encrypted network, and from this release the Android host does too (see
Security above), so the host's own window never writes messages to the disk outside the database's key.
Nothing changes for phones joining a network.
Additional fix included in this tag
- The Mac app carries Electron’s licence files (
LICENSE.electron.txtandLICENSES.chromium.html) in its Resources directory.
Full changes: v0.6.4...v0.7.0
LOAM 0.6.4
The app is the same as 0.6.3. Only the version number changed.
LOAM on Google Play is now signed with the same key as this APK, so the Play and GitHub versions can update each other. Play wouldn't accept 0.6.3's version code a second time after the key change, which is why this is 0.6.4.
Updating
0.6.4 installs over 0.6.1, 0.6.2 and 0.6.3 as an update. If you still run 0.5.0 or 0.6.0 (com.loamnet.host), read the 0.6.1 notes first: the app's name changed there.
Verify the download
shasum -a 256 -c loam-host.apk.sha256
gh attestation verify loam-host.apk --repo MagicZebraLtd/loam
The APK is signed with the same key as earlier releases.
LOAM 0.6.3
LOAM 0.6.3 adds new-message notifications and makes the Android host explain a failed start instead of closing. Full details are in the changelog.
Notifications for new messages
Settings has a Notifications section: a sound and/or a buzz for direct messages (the default), every message, or nothing, saved on each device. Browsers don't allow real notifications from a plain-HTTP local network, so in a browser these play only while LOAM is open.
On the Android host phone, the host's own new messages show as Android notifications while LOAM is in the background, one per conversation, following the same choice. The lock screen shows only "New message", a tap opens the conversation, and an Emergency reset clears them. They never leave the phone, and they use the notification permission LOAM already asks for.
When the host can't start
If another app on the phone is already using LOAM's network port (3000), the Android host now says so in the phone's language and offers Retry, instead of closing. LOAM also no longer treats an answer on that port as its own server, so another app can't get LOAM's window or its host token.
Smaller changes
- "Try another name" on the Welcome screen is a proper button.
- The host counts "Devices connected", since laptops and tablets join too.
Updating
0.6.3 installs over 0.6.1 and 0.6.2 as an update. If you still run 0.5.0 or 0.6.0 (com.loamnet.host), read the 0.6.1 notes first: the app's name changed there.
Verify the download
shasum -a 256 -c loam-host.apk.sha256
gh attestation verify loam-host.apk --repo MagicZebraLtd/loam
The APK is signed with the same key as earlier releases.
LOAM 0.6.2
LOAM 0.6.2 makes two changes before the Google Play release. Full details are in the changelog.
Two new rules: no nudity or sexual content, and no gore
Graphic pictures or videos of violence or injuries are allowed only to get someone help. The rules are now version 2, so everyone already on a network sees the Welcome screen again and agrees once more before their next post. The new rules are on the Welcome screen and at /rules, in all 15 languages.
No usage reports to Google from the QR scanner
The Android app reads link codes in setup with Google's ML Kit. ML Kit reports the phone's model and Android version, the app's name and version, a per-install id, timings and error codes to Google, and has no setting to turn that off. 0.6.0 and 0.6.1 sent those reports, when the phone had internet, after the scanner was opened. 0.6.2 removes the library's upload route, so the reports are discarded on the phone. Nothing from a LOAM network was ever in them.
Updating
0.6.2 installs over 0.6.1 as an update. If you still run 0.5.0 or 0.6.0 (com.loamnet.host), read the 0.6.1 notes first: the app's name changed there.
Verify the download
shasum -a 256 -c loam-host.apk.sha256
gh attestation verify loam-host.apk --repo MagicZebraLtd/loam
The APK is signed with the same key as earlier releases.
LOAM 0.6.1
LOAM 0.6.1 renames the Android app to com.loamnet.app, the name it has on Google Play. Nothing else changes: the web app, the server and loamnet are the same as 0.6.0, whose notes list everything new in this release line.
If you host from an Android phone with 0.5.0 or 0.6.0 from GitHub
Android treats com.loamnet.app as a different app from the old com.loamnet.host. Installing 0.6.1 does not update the old app: it installs beside it, and nothing carries over. The new app opens with the setup screens and a new, empty network.
Uninstalling the old app permanently deletes everything its network stored on the phone: messages, pictures, files and settings. Keep it until that network is no longer needed, and run one of the two apps at a time.
Later updates install over 0.6.1 as usual.
Verify the download
shasum -a 256 -c loam-host.apk.sha256
gh attestation verify loam-host.apk --repo MagicZebraLtd/loam
The APK is signed with the same key as earlier releases.
LOAM 0.6.0
LOAM 0.6.0: the Play launch release. A Welcome screen with the network rules (LOAM is for adults), reports moderators can act on, setup screens and display mode on the Android host, link and invite codes, a terminal screen and kiosk mode for loamnet, tablets and Android laptops, and every finding of the 9 October 2026 review.
Full details: CHANGELOG.md.
Android host (loam-host.apk, Android 8+, arm64)
- Setup screens. The first launch asks for a language, the kind of network (Private and short-lived, Community, or choose every setting), its name, and Hotspot or Wi-Fi. Later launches continue the last network in one tap.
- Display mode shows the join codes full screen, keeps the screen on and pins LOAM in front; leaving it takes a press-and-hold.
- Link another LOAM node from the share screen with a one-time code; the other phone scans it in setup and the two networks share their public channels both ways. Invite codes on approval-only networks let a scanned phone straight in.
- Tablets, foldables and Android laptops: portrait and landscape, resizable windows, keyboard and mouse. Wi-Fi mode hosts on a wired network too.
- A clearer host menu, Emergency reset behind a three-second hold, About LOAM, saving received files, and update news on the opening screen only (the Play build asks the Play Store app; this GitHub build has a tap-only "Check for updates"). Nothing is downloaded automatically.
- Every native screen, error and the hosting notification follow the chosen language (15 languages; Arabic, Persian, Dari, Pashto and Urdu read right to left).
- Permissions: Android 13+ asks only for Nearby Wi-Fi devices; location is requested on Android 12 and older only.
Web app
- Welcome screen and rules. New members see their random name and picture, the rules in one sentence, and "I'm 18 or over, and I agree". Until they agree the node refuses posts, reactions, uploads and typed names; reading, reporting and blocking always work. The full rules are at
/rules, offline, in every language. - Reports moderators can act on: the reported message shown live with its pictures and files, Escalate to admins, and a live count of open reports on People.
- Direct Messages lists your conversations, with a searchable picker for new ones. Light or dark theme. 15 reactions in a grid plus any emoji from the keyboard. Search with highlighted matches. Invite: Copy link. The privacy policy is served by the network itself.
- The installed app's service worker precaches every file, so it opens offline from the first visit; one request answers every page load, so conversation ids never reach the network.
loamnet (npm)
- A terminal screen: the join QR stays on screen, with Activity, People, Settings and Debug a key away.
oopens LOAM in the browser as the network's admin. Kiosk mode (kor--kiosk) shows only the join QR until a password is entered. - Admin now comes from the host's own screen, never from being first to join. Free-port fallback when 3000 is taken. The CLI needs Node 22.14+ (the SQLCipher driver is v13, no install script).
Security
- Encrypted replies are tied to the request that asked for them, and the web app refuses a reply whose encryption was stripped mid-session.
- The node serves only requests addressed to it (IP,
localhost,.local, or the advertised join host), which shuts out DNS rebinding; the WebSocket refuses pages from another origin or another port of the same host. - Joining by QR code no longer loses the network's key on the first redirect (every release since transport encryption arrived was affected).
- Emergency Reset is journaled on every kind of node and finished by the next boot if interrupted; plaintext databases overwrite deleted rows and the reset compacts the file.
- Sync and mesh hardening against hostile peers: bounded channel introductions, clamped timestamps, refused re-authoring of local users, remembered refusals, hop-budget and send-time jitter on mesh mail, canonical key checks.
- Encrypted-session caps per device identity and per-address claim, panic and connection limits on IPv6 networks.
- The data directory is private to the node's user (0700/0600). Private channel ids no longer leak the existence of a same-named channel. The panic route sends no rate-limit headers.
- Supply chain: vendored, checksum-pinned SQLite packages for the Android build,
pnpm auditin CI, a day's minimum release age for dependencies, and build provenance attestations for the APK and the Play bundle. Verify withgh attestation verify loam-host.apk --repo MagicZebraLtd/loam.
Still unverified on hardware (docs/25 §0): SQLCipher key, rekey and wipe on a physical phone; the hotspot permission flow on Android 12 and 13+; the hosting notification and foreground service on a phone; Windows durable writes on a real Windows machine.
Verify the download
shasum -a 256 -c loam-host.apk.sha256
gh attestation verify loam-host.apk --repo MagicZebraLtd/loam
The APK is signed with the same key as 0.5.0, so it installs over it as an update. The CLI is npx loamnet@0.6.0 once published to npm.
v0.5.0
LOAM 0.5.0 — the pre-release review release, plus a Wi-Fi hosting mode and a redesigned client.
Android host (loam-host.apk, Android 8+, arm64)
- Wi-Fi hosting mode. Share · Host now opens with a Hotspot / Wi-Fi choice. Wi-Fi mode hosts on the network the phone is already on: no hotspot, no location permission, one join QR for everyone on that Wi-Fi. Hotspot mode is unchanged and stays the default.
- The host phone's own screen claims admin with a per-boot token, passphrase mode asks at every start, device-to-device transfer no longer copies the database, and an encrypted database fails closed if its driver won't load.
- The native screens use the client's palette, and the WebView shrinks for the keyboard.
Client
- Redesigned: an earthy palette in light and dark, native fonts only, bubbles with the time inside, grouped messages, hover or long-press actions instead of a permanent icon row, a pill composer, card-based settings and admin, proper confirmation dialogs, coalesced toasts. Renders on old Android WebViews and in the five right-to-left locales.
- The keyboard no longer pushes the header off screen; the message list stays on the newest message when it opens.
- Blocking, Report this user, channel Delete, a privacy policy link, and every non-English locale complete.
Security and server
- Fail-closed key pinning (a changed node key shows a rescan gate, never a silent swap), plaintext transport no longer configurable, sync imports hardened, mesh replay protection, wipe races fixed, the 9.4k-line
app.tssplit into modules. SeeCHANGELOG.mdfor the full list and the upgrade notes.
Upgrade notes
- Channels archived under the old semantics reappear as read-only; use Delete for gone-for-good.
- A
config.jsonwith"transportEncryption": "off"now boots asoptional. - An updated Android install keeps hosting in Hotspot mode; pick Wi-Fi on the Share screen to host on an existing network. The Wi-Fi mode and the WebView keyboard fix are compiled and unit-tested but not yet verified on a physical phone.
Full changelog: https://github.com/JosephMaynard/loam/blob/v0.5.0/CHANGELOG.md
v0.4.0
v0.4.0 — device-feedback fixes + dependency bumps - Android host: hotspot join QR targets the hotspot gateway (STA+AP fix). - Client: hide disabled profile/avatar sections; fix the "Open admin area" link. - Deps: jsdom 30, js-sha256 1.0; Node pin -> 24.15.0. - docs/21 passphrase check corrected. On-device verification still pending.
v0.3.0
LOAM v0.3.0 First release-signed build (CI-signed APK attached to this release). - On-device LLM working, encryption + crashes fixed (device-verified) - LLM DM-context bound; 256KB sync-import body cap - Docs/README/site accuracy pass; consolidated backlog + AT-Proto/Electron plans Pre-1.0 — still early.
v0.2.0
LOAM v0.2.0 First device-tested release. - On-device LLM working (llama.rn native libs packaged) - Encryption + AI Model crashes fixed (RN bridge removeListener) - WhatsApp-style chat UI + polish - Android host UX (safe-area, hamburger, back button, package name, invite modal) - APK-on-tag CI (this release's APK is built + attached by GitHub Actions) Pre-1.0: still early, expect rough edges.