Releases: richhabits/sam
Release list
SAM 3.6.0
Signed build — installed apps auto-update to this.
Highlights since v3.5.0:
- New mobile design (tab bar, Home, Vault browser, job detail sheet, samKit component library, F0824E accent)
- Safe-aware key save fixes (locked-Safe save no longer silently reports success, plaintext-.env bypass closed, concurrent-write race fixed, cleared keys stay cleared)
- Windows DPAPI key unlock fix
- FLIP IT button wiring fix
- Right-click context menu (Cut/Copy/Paste)
- Electron 44 migration
- Dependency security fixes (npm audit clean)
SAM v3.5.0 — The Cut
SAM v3.5.0 — The Cut
Two weeks of work that had shipped to main but never reached an installed app until now.
New this release
- Android is real. A native Android build now exists alongside iOS — signed keystore, a real signed AAB, cleartext-traffic fix. Same app, same features, one shared codebase with iOS.
- SAM can fix itself again. The self-repair bots (label an issue, SAM attempts its own fix on a free model) had been silently dead for about a month on an expired credential — they degrade and tell you what broke instead of dying silently now, and both are verified working end to end.
Faster
- The build/automation system runs jobs at the same time now instead of one at a time. A job for an untouched project no longer waits behind everything else in the queue.
- Live previews of your own builds no longer show a blank page — this was breaking for any project with a real build step (the exact kind of project the system itself recommends building).
More reliable
- Fixed a case where jobs sent through the real background daemon could silently never start.
- Continuous integration had been red on the main branch for three pushes without anyone noticing — a lint issue and a Windows-only test bug. Both fixed, and the daily health check itself was quietly skipping half its checks on the mobile app — fixed too.
- A security-relevant networking library was bumped to patch a real, disclosed vulnerability, and the code that guards against server-side request forgery was hardened against the change.
- An image-fetching path inside the Studio feature now goes through the same request-forgery guard everything else does.
Mobile
- Native tactile feedback (haptics) across iOS and Android.
- The standalone AI mode (works without pairing to a desktop) now has over 30 fallback providers instead of a handful, with an honest failure message instead of a made-up answer when everything's exhausted.
- iOS build submitted for review with a fix for a narrowed network-security setting that was breaking the app for Tailscale/VPN users.
- One-tap code copy, haptic feedback, and a status pill showing exactly what's connected.
Health & hygiene
- All 9 previously open dependency-security alerts closed — 6 upgraded, 3 dismissed with a written reason (build-tool-only dependencies that never ship in the actual app).
- Two flaky tests that intermittently failed in CI (real DNS lookups against invalid hostnames) now run instantly and deterministically.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
bd5e3d02336d67a093c15939c262467ffb726d8ecde6dd95af628c5f4af0fb30 SAM-3.5.0-arm64.dmg
1c0456437a29f7bec19d30da643e80e0bacafebf2ed63fb4250a3790afc035b9 SAM-3.5.0.AppImage
59aaff8233f3670b55fe29b99c3b8ab2e49180382d4c8448f746c2587fff8626 SAM-3.5.0.dmg
28dbd21a977252bcf5d462ef072f18569c6af7007842f43863097e41135465e2 SAM-Setup-3.5.0.exe
4ec9946b735a0be70ccf1dc7b9217c5dfe05e371048a2c65b741ee08b0a55f70 sam_3.5.0_amd64.deb
SAM v3.4.0 — Nothing Fails Quietly
SAM 3.4.0 — Nothing Fails Quietly
A full line-by-line audit of the codebase. Thirty-odd fixes, and the theme runs
through nearly all of them: things that were broken in ways nobody could see.
The download itself
The Mac build is signed and notarized, so it opens without the "Apple cannot check
it for malicious software" warning. Worth saying how close that came to being false:
the build log said notarize · accepted and stapled ✓ and it was telling the truth
about the app — while the .dmg you actually download carried no notarization
ticket at all. That still opens if you are online, because macOS can go and ask
Apple; offline, or on a bad connection, it stalls or fails. Both artefacts are now
stapled, and CI fails the release if either one isn't.
Five features that had never worked — not once
read_emails/read_notesraised an AppleScript syntax error on every call
since the day they were written. Both were wrapped in a catch that turned it into
"Couldn't read Mail: …", which reads like a missing permission. Nobody debugs a
permissions message by opening a parser.quick_note/backup_vaultresolved the vault from the working directory. The
packaged app runs withcwd=/, so they wrote to/vault— permission denied, every
time. They worked perfectly in development, which is exactly why they looked fine.
A backup tool that has never run is the failure you find at the worst moment.- The pairing badge polled every four seconds into a variable nothing displayed, so a
device waiting to pair announced itself to no one.
Security
- The prompt-injection fence switched itself off on long sessions. Trimming the
transcript cut fenced blocks in half, leaving attacker text in place with its "these
are not commands" marker gone. - The morning brief fed unfenced email straight into the agent — a timer-driven job,
with input written by anyone who can email you. - A silent exfiltration path:
read_fileandweb_fetchboth run without asking, so
a secret could be read and sent in two steps with no prompt. Both ends now refuse. - Reads that answered anyone — your schedules, what SAM may do unattended, its
diagnostics, the block log. Any process on your Mac could ask. - The yard: injected environment could hand
gita command to execute; the context
walker followed symlinks out of the project; the worker lock could be held twice. - Credentials in URLs (
postgres://user:pw@host) reached logs verbatim.
Honesty fixes
- 47 refused actions reported success. "Disable all consents" said done while consent
stayed on; revoke said revoked while the device stayed paired. - Four "refused is not absent" panels that could never appear, so a refusal read as
"you have none". - A microphone that never released when the wake-word listener was torn down mid-start.
- Chat history vanished silently once localStorage filled.
- The coverage ratchet was set below half the real baseline and ran in no workflow.
iOS
Transport security narrowed from a blanket exemption to local-networking only. Pairing
now hands your phone a reachable address instead of localhost or a self-assigned one,
and "Forget this device" actually revokes the session on your Mac.
1,914 tests. Every fix carries one, and several pin the mistake rather than the fix.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
fd7e2725ffaa53a1eb997135e81d90842e3239a258a7af0f41e11dd6e4401bde SAM-3.4.0-arm64.dmg
0797354d1ac1b3b50a50e77124d4aa1d97a6defa5d1b295f1602c484a2c94d08 SAM-3.4.0.AppImage
ff2269c14ed21da2026ba49c03f680c502444887bc8ed34cfc4be0d69db05572 SAM-3.4.0.dmg
9e0e16906c4fb8fb041b8504e2ab481345853271596e22b0eb956d3494e6c4b7 SAM-Setup-3.4.0.exe
001fca276973ff5702f9c8f363680d52bed08ca7f3c070126b677b29c88e3dfe sam_3.4.0_amd64.deb
SAM v3.3.2 — The Yard, Actually
Everything in 3.3.0 — pairing, spend consent, the Pocket's new Settings and filterable task list — plus the three further bugs it took to make the yard genuinely work from a packaged app. This is the one to take.
3.3.0 claimed to fix the yard. It did not, and neither did the first attempt at fixing that. Each bug hid the next.
Fixed
yardDir() never detected a packaged app. It asked whether ROOT contained app.asar — and ROOT is join(dirname(module), "..", ".."), where join normalises. For the bundled layouts a packaged app actually runs, the .. segments eat the app.asar component:
| module | ROOT | contains app.asar? |
|---|---|---|
app.asar/server/yard/store.ts |
…/Resources/app.asar |
yes |
app.asar/dist/server.mjs |
…/Resources |
no |
app.asar/dist-electron/x.js |
…/Resources |
no |
Only the unbundled source layout matched — the one layout a packaged app never uses. The question is now asked of the module path, before normalisation.
The yard could not open its database. server/db.ts exists to pass SAM_SQLITE_BINDING (the native binary that lives outside the read-only asar), and server/yard/store.ts called new Database() directly, skipping it. The app died with Cannot find module .../app.asar/build/Release/better_sqlite3.node the moment the yard was switched on.
The packaged app had no worker at all — the yard · no worker entrypoint — staying down. The electron main bundle lives in app.asar/dist-electron and the worker in app.asar/dist; they are siblings, and every candidate path missed by exactly one level. The store opened, the API answered, and no job would ever have run.
The yard worker could never start on Windows. npm writes tsx, tsx.cmd and tsx.ps1 into node_modules/.bin; the supervisor took the first that existed, and Windows cannot execute a POSIX shell script.
Changed
The release smoke test now proves the thing it claims. It used to boot the app with the yard off — never opening a database, which is the one thing that breaks in a packaged build — and with the checkout as its working directory, so the app ran the repo's TypeScript worker instead of the bundled one. It now runs from a clean directory with the yard on, and fails if the boot log carries an uncaughtException, if the yard cannot find its worker, or if no database appears.
A test also forbids opening a database anywhere but openDb(). It was checked against the file that shipped in 3.3.0, and fails on it.
Signed with a Developer ID certificate and notarized by Apple.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
3c4bb98fe38ab973cd781475a7db4302af8464a34faab12f6b45be3033d9472d SAM-3.3.2-arm64.dmg
8fc7eadfe71a598a7beb24a735f442ab498367809cb63d5c2627d9c765901de4 SAM-3.3.2.AppImage
68429c238b5ee4b09634ba82a5562134cbb7b1e5be579d97ec567781d13cfb2b SAM-3.3.2.dmg
544f800e9ba84a8b7147acf3ceb0daca6cdcf0665f352d9b4664468cbfe3f011 SAM-Setup-3.3.2.exe
2bd6f2c7bea425a4b77600d46da23f2faadb7fb0d9c2dd36b9cd3ad507261d26 sam_3.3.2_amd64.deb
SAM v3.3.0 — The Pocket Connects
The release where the phone app stops being a demo of itself. Two things in SAM had never actually worked end to end — pairing a phone, and the yard when SAM runs as an app rather than from a checkout — and both failed in ways that looked like your fault.
Fixed
The yard could never work from the packaged app, and said only "500". yardDir() derives from its own module path, which inside SAM.app resolves to a directory inside app.asar — a read-only archive. Every file the yard owns (jobs.db, paired.json, worker.lock, logs/) failed to open, and /api/yard answered a bare 500 to a phone that was correctly paired. The yard has only ever worked when the server ran from a checkout, which is exactly why the launchd daemon could serve it and SAM.app never could. Packaged builds now keep state under ~/SAMYard; a checkout keeps its repo-local yard/, so no existing job moves.
The status endpoint no longer answers with a shrug either — it returns 200 with the path it could not read.
You could not pair a phone at all. POST /api/pair/new mints the code, and nothing in the app had ever called it; the desk pointed at a button that was never built. There is now a "+ Pair a phone" button that calls it.
A refusal from before pairing outlived the pairing that fixed it, locking the phone out of a SAM it had just been granted. And the desk no longer offers a pairing that cannot work when a second SAM already holds the port.
Security
Anyone on the network could mint a pairing code under SAM_REMOTE=1 and claim a full session. The cause was middleware ordering, not a missing check. Remote mode is off by default.
Added — the Pocket
- It asks before it spends. A paid brain needs consent, and the grant can be taken back from Settings — it used to be a one-way door, which is not a permission.
- A demo, so the app is not dead without a Mac — sample data, labelled as such on every screen it reaches.
- Settings that contains settings: spending, appearance, version, help, and an icon on every row.
- A task list you can filter — the Running / Queued / Failed / Done counts became the control that opens the rows behind them.
- A job says what it DID, folded from its own step list, instead of printing a timestamp.
Changed
- The tint stopped being a status. Terracotta meant "running" in one place and "this is a link" in another; colour now carries one meaning, and running is carried by motion.
- The palette was failing AA on the most repeated text in the app — fixed, including under Increase Contrast, which the app now honours.
- Four different logos were shipping as SAM. One mascot now, everywhere.
- VoiceOver was reading parts of the app out as punctuation.
Build
build:mac:signed packaged whatever was already in dist/ — every other target runs preflight and a build first. A release cut that way carries the last build someone happened to run, possibly predating the fix it was cut for, while reporting the new version number. It now builds first, makes skipping notarization an explicit flag, and refuses to upload an unnotarized build as a release.
Signed with a Developer ID certificate and notarized by Apple. Gatekeeper's own verdict on this build: accepted, source=Notarized Developer ID.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
5efc259cda02b153a914525d930fdbeeedcf6a7cd4dfedab7e4c293b91274780 SAM-3.3.0-arm64.dmg
e4962824923c69edbcfe5510fad4f83da51c066a4b6aa8fbf50812c55a917cb5 SAM-3.3.0.AppImage
51f341a568c3eeca285a597a22a675ab41992039f64ca49844b4198249cee651 SAM-3.3.0.dmg
09bc24d5b91ee632197b7c268e2d888b64ceee02b42e654233b887c966e50358 SAM-Setup-3.3.0.exe
f437d9ebdc38358e116b0518e60b841d8f76709480ddb5a1cbb3361d40bfe3db sam_3.3.0_amd64.deb
SAM v3.2.4 — Zero Known
Nothing changes in the app. This is 3.2.3 with four dependency advisories patched — plus an honest correction to which Node versions SAM actually runs on.
Security
Four advisories were published after 3.2.3 shipped, three of them in the production tree. Nothing in this repo changed to cause them; the advisories are new.
| package | what | |
|---|---|---|
| high | ip-address |
leading-zero octets decoded as decimal where resolvers read octal — an SSRF and trust-boundary bypass |
| high | fast-uri |
host confusion via a backslash authority introducer |
| moderate | hono |
ReDoS in the CORS middleware |
| moderate | undici |
response desynchronisation via the retry interceptor |
Lockfile only — no dependency was added, removed, or changed.
The ip-address advisory names the exact class of attack SAM’s own SSRF guard exists to stop, so to be clear: it is not in that path. It arrives via @modelcontextprotocol/sdk → express-rate-limit, and SAM only ever constructs an MCP client over StdioClientTransport — it never runs an MCP server, so that middleware never executes. server/url-guard.ts does its own resolution and never references the package.
Changed — running from source now requires Node 22.19+
This is not a new restriction. It has been true since undici went to 8.x, which refuses to load below 22.19. What was wrong was everything that described it: engines advertised ^20.19.0 || >=22.12.0, .nvmrc and .node-version pinned 20, the README asked for "20.19+ or 22.12+", and setup.sh waved through anything >= 20.
So someone following our own instructions exactly got a working install and a broken app — the URL guard and all four web-intel modules fail to import on Node 20. All five now state 22.19, and setup.sh checks the minor version, because 22.12 was permitted by the old text and is not good enough.
If you use the packaged app this changes nothing for you — it bundles its own Node 22. This affects running from source only.
Verified on Node 22: typecheck clean, 1522 passed / 2 skipped across 127 files, build clean, lint clean, no stats drift.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
cea1b90a57ca26cbb0fe7552263bade8ac9ff52fd8d58f0ba3445fc0546bb7a0 SAM-3.2.4-arm64.dmg
df41192afb25c1adc22452b98b200c32250bf0817bf6586d492629a9fd106c96 SAM-3.2.4.AppImage
22e460781501c25dfa74620e1c525ea088f4d4704b87debeedd9a32b7fe90a36 SAM-3.2.4.dmg
cdf0745f16c367f59f052eaff3f0f9d12d69eaf9f0c68c9a5a36cf80f28ba90b SAM-Setup-3.2.4.exe
8070d6895c1cc1a79005bb2b6f2f12485d5c2c4065376021d3881ff64539a27c sam_3.2.4_amd64.deb
SAM v3.2.3 — Proof Before Publish
Nothing changes in the app. This is 3.2.2 with its Windows download named correctly.
Fixed
- Windows: the installer was published under the wrong name. electron-builder writes that
file with spaces in it, and GitHub turns spaces into dots when a file is attached to a
release — so the download arrived asSAM.Setup.3.2.2.exewhile the update feed, and the
one-paste installer, both looked forSAM-Setup-3.2.2.exe. Nothing errored: the release
looked complete, and then every Windows update quietly failed and the install script reported
no installer found. 3.2.2 has been withdrawn. The file is now named without spaces, so there
is nothing left to rewrite.
Changed
- A build is published only after it has been proven to start (this is what 3.2.2 was for).
Packaging used to upload the installers as part of building them, with the check that boots
the app running afterwards — a report rather than a gate. 3.2.0 is what that cost. The order
is now build → boot it → check the signature stuck → upload. - The upload step now also refuses to publish if the update feed points at a file that is not
actually attached, which is exactly the fault above. Both of these failures were invisible
from the outside: the download works, and only the next thing quietly stops working.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
e5c65d22c5c4e86636955f8af499d781e66ff4365bc0bf9ebdfd79c93c7fadfd SAM-3.2.3-arm64.dmg
bad0751cf2992ad8bfad41155574544233a6c12b3ca09028e6b7c2e42dcf4d59 SAM-3.2.3.AppImage
d4f5a52d585d4d1a0795bc07e061bc39624a3857a56b70ed7a2d9db6d50c8a08 SAM-3.2.3.dmg
ac3191cb5ca83499d556f9382d4c7cc176b48a98f63fb10d363e02b0b9932d69 SAM-Setup-3.2.3.exe
0bd308c352498382fa134ea393f0eda577b19c93e75a474de0bbc688c6e5521e sam_3.2.3_amd64.deb
SAM v3.2.1 — The Deliverable
3.2.0 was withdrawn — it did not launch. This is that release plus the one-line fix that makes it start. Everything below is what 3.2.0 was going to bring.
3.2.0 did not launch. Please use this one.
Fixed
-
The packaged app crashed on startup. better-sqlite3 13 moved its native binary from
build/Release/better_sqlite3.nodetoprebuilds/<platform>-<arch>.node, and the code that
points the app at that binary still looked only at the old location. Missing it is silent: the
app then let the library find its own copy, the library looked inside the read-only archive
where no such file can live, and the whole thing died before the first window. Confirmed on
Apple Silicon and Windows.Nothing in the test suite could have caught it — the tests, the type check and the linter all
passed, because none of them run the packaged app. What caught it was the smoke test that
boots the real build, after the installers had already been uploaded. 3.2.0 has been withdrawn.Both layouts are now checked, and a test asserts that the installed library still keeps its
binary somewhere the app looks — so the next version that moves it fails in a second instead of
in a release.
SAM hands you something now. Ask for a deck and get a deck; point it at a spreadsheet and get
what's wrong with the data rather than the data back. And the phone stops being a viewer.
Added
- Slide decks. Ask for one and SAM writes the whole thing — structure, content, a
presentable HTML file saved to your vault. It opens offline and prints to PDF, because the
deck is a single self-contained file with nothing loaded from anywhere. No charts for exactly
that reason: charting libraries come from a CDN, and a deck that needs the internet to render
is not a file you can rely on in a room. - Spreadsheets and CSVs, read properly.
analyse_dataprofiles a file instead of dumping
it: what each column actually is, and then the things that are wrong with it — duplicate rows,
columns that are 90% empty, one column holding two kinds of value because someone typed "N/A"
into a number field, values sitting miles outside the rest. Those findings are the point; the
table is the evidence. Bounded (8 MB / 50k rows) and it tells you when it truncated, because
stats over a silently clipped sample are worse than no stats. - Home and Lock Screen widgets on the phone. Quick actions that open SAM ready to go. A
widget link pre-fills what you're about to say — it does not send it, because any app on your
phone can open a URL and none of them should be able to put words in SAM's ear. @a past task on the phone. Type@, pick something SAM did earlier, and its context
rides along with your next message.
Changed
- The Pocket works on iPad. It claimed to since the day it shipped and nothing in it ever
looked at the window size, so on a 12.9" screen it stretched rather than adapted — chat set to
a thousand-point line, a pairing form running the full width. It now lays out for the window
it is actually in, which is the honest test: an iPad in Slide Over is a phone-shaped sliver and
should look like one. - The app icon is SAM's own mark, drawn at full resolution instead of a different picture
scaled up. brew install --cask richhabits/tap/samtracks releases again. The cask had been stuck at
v1.5.0 for six months while the step meant to bump it skipped in silence. The tap updates
itself now — nothing to provision, nothing to forget.
Fixed
- Seven more read routes were open to any program on your machine. The 3.1.1 sweep stopped at
files; these read you — a running account of what SAM did and what it asked you to approve,
what it has learned about you, the folders you watch, your usage./api/proactivewas the
worst of them: reading it drained it, so anything that asked ate your briefings instead of
copying them. None of it is a credential, which is exactly why it was passed over twice. - Several smaller ones found by turning the security scanner up rather than waiting: a biased
draw in a pairing code, a regex an attacker could make crawl, HTML entities decoded twice so
that text could become a tag, a spreadsheet cell able to break the table it was rendered into. - Zero known vulnerabilities, including a high-severity denial of service in a build
dependency.
Internal
- Node 20 reached end of life in April; everything moved to Node 22, which also unblocked eleven
major dependency upgrades that had been stuck behind it — Express 5, React 19, TypeScript 7. - Two failures that had been hiding themselves: a pull request with a conflict reported nothing
rather than "conflict" (every check silently skipped), and a release step that silently
published nothing. Both are loud now.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
a45320252471dda8dd604325bc2a3a6d56ef6e919631d8932ed8f8ee6af07dad SAM-3.2.1-arm64.dmg
3f85693e5bef563ba1cd42aeae99c5b0f00f503754998e55c813925b94ffb650 SAM-3.2.1.AppImage
8e9a1be59cbfc316cdfcbd61b0553241c15be6afc7811c3ad4ed2d0a22f234d4 SAM-3.2.1.dmg
d4d16462461d281d7a0d6e60227a5b869c12c3dede4a703ef4e2d33af097bc3d SAM-Setup-3.2.1.exe
222c020455336b2407b6bf0fe1da3d3312a8d8250bb72831cd3447cedfd3065e sam_3.2.1_amd64.deb
SAM v3.1.1 — One Bar
A security fix. SAM held writing to a high bar and quietly let reading through.
Fixed
-
Your notes were readable by any other app on this Mac.
/api/vault/log,/api/vault/graph
and/api/vault/statsanswered any request that reached the loopback port, with no credential
at all. The guard on the privileged routes asks whether a request is a mutation — and a GET
never is, so every read walked straight past it. What leaked is note titles, timestamps, the
vault path and a graph built by walking the whole vault. Not credentials, and not remotely
reachable — but any process on your machine could ask, including a supply-chained dependency
inside some unrelated app, and it never had to know a secret.Reads of your private content are now held to the same bar as a change: the desktop app's
per-launch passkey, or a session you approved by pairing. Every real client already carries
one, so nothing you use loses access — the app sends the passkey, a paired browser its cookie,
your phone the same token as a Bearer.If you run SAM only as the desktop app on a machine where you trust every other program, the
practical exposure was small. Update anyway; the routes were open to anything. -
The keepalive was not keeping anything alive. If you installed the launchd agent with
scripts/install-server-daemon.sh, it pointed at a built server path that no longer existed,
so every start died instantly and launchd tried again five seconds later — 60,104 failed
starts and 28 MB of identical stack traces, while SAM appeared simply to be down. A dead
keepalive is quiet, and a crash-looping one is quiet in the same way.launchd cannot make this call on its own: it cannot tell a crash apart from a start that
should not have happened, and both normal reasons to hold off — the repo's drive not mounted,
or the desktop app already serving the port with its own passkey — look exactly like a crash.
A supervisor now makes that decision, waits quietly instead of looping, and stands down when
something is already serving. It also no longer carries a fixed control-channel token in a
world-readable plist, which handed the Handshake's secret to the very processes it refuses.Only affects people who installed the agent; it is not part of the packaged app.
Internal
- The CI secret scan had been failing for weeks on two key-shaped test fixtures in the phone's
scrubber test — placeholders it needs in order to prove it redacts them. Allowlisted like the
server's equivalent. Worth knowing that it did not reproduce on a current local gitleaks; CI
pins an older version whose rules still flag them.
Security
- The same hole reached further on unreleased code — the GitHub, Slack, Notion, Linear and Vercel
connectors were built on the same unguarded reads. Those landed after v3.1.0 and were fixed
before they ever shipped, so no released build ever exposed them. Recorded here because the
fix is public and the shape is worth knowing.
🔒 Verify your download (SHA-256)
The one-paste installers verify this automatically. To check by hand, compute the hash and match:
- macOS/Linux:
shasum -a 256 <file> - Windows (PowerShell):
Get-FileHash <file> -Algorithm SHA256
c0792fead58765dcad9ca7a04a03dd3c26f06d0e61b3086d53f3219750e6170f SAM-3.1.1-arm64.dmg
6eb597accefc90b8dbc119c01fef65926563cfcfa408dc58c45f0e28f7cf6a14 SAM-3.1.1.dmg
19404714a90b91be5d7cc1e55658cf78fe295f9a58e71ee70556c12708ef5bb2 SAM-Setup-3.1.1.exe
684237287cc244c0d0250a5cd83683c703b3695859f331efa7502f455cf88427 SAM-3.1.1.AppImage
6c98cc3a36aeb188c7ef3c6f970a7c36241aad0b0835b56f2603db1e7db24487 sam_3.1.1_amd64.deb
v3.1.0 — The Pairing
Browsers and your phone can now use SAM — securely.
SAM's security lock (the Handshake) is on by default, which meant a browser tab or phone couldn't get in. Now they can: open SAM in Chrome or on your phone, click the one-time pairing link SAM shows you, and you're paired — the lock stays on the whole time. Ten seconds, and it sticks (30-day sessions, revocable).
Also: the biggest security + reliability pass in SAM's history — three deep audits, 100+ fixes.
- 🔒 Closed a raft of ways a rogue local process or a malicious web page could have driven SAM (which holds deploy tokens, your files, git). Secrets locked down at rest.
- 🎯 Web research finds sources with no key; the camera and contacts work; error messages now name the real problem instead of blaming a missing key.
- 💾 Keys you add now reliably save.
- ⚙️ Background jobs can't double-fire, and your data can't be lost to a crash mid-write.
Free, private, local-first — same as always. Tap Update, or download below.
Verify your download
shasum -a 256 <file> (macOS/Linux) or Get-FileHash <file> (Windows) should match:
d1d198c8ba8309203acb8b2bb89d976720ebc39c7ca1f022fac65fc4668d9c21 SAM-3.1.0-arm64.dmg
c3dc5d656c14b92155e4a132f73ed14d0df36bb91a5ba845aead5ae487cd815d SAM-3.1.0.AppImage
fe2a6cb19bbb9e1d2a12403a5a2c421497329724f6e22b7c1b79ceb151f6f4e0 SAM-3.1.0.dmg
a961deb6e7bc00b3b4f04bf319d5ca3df5b864cc740a73e3fe4e48926d669418 SAM-Setup-3.1.0.exe
ab5d599ec2905b0f9e457790e9e2f2d900fece797e6da8a96c03b9eb4ec4c9ac sam_3.1.0_amd64.deb