Skip to content

Blog

The public package audit after the Studio launch.

Abstract release chain diagram in raspberry on graphite.

Two version lines, on purpose

The public surface has two version lines: @memi-design/cli@1.1.0 on npm, and Mémoire Studio 1.0.4 as the signed macOS app (tag v1.0.4, 2026-06-07). They are independent by design. Studio 1.0.x rides on runtime v0.18.4, pinned in the app’s package.json under memoireRuntime, so the CLI can move when the engine changes and Studio can patch OS and lifecycle behavior without pretending the package changed.

The split is the easy decision. The consequence is the hard part: two version lines fan out into four public surfaces (npm, GitHub Releases, the Homebrew cask, and the website download page), and each one can drift on its own schedule.

Each audit line is a scar

We did not invent the audit out of caution. It accumulated one failure at a time, mostly inside the first 48 hours of having public releases at all.

The first DMGs went out signed but unnotarized (commit 9dcf306, 2026-05-10). CI was green, the GitHub release existed, the download link worked. Then spctl rejected the app as “Unnotarized Developer ID” on a real Mac. Everything upstream of the user’s double-click had passed; the double-click itself failed. The fix was an explicit xcrun notarytool submit --wait plus stapler staple, so Gatekeeper can verify the app offline instead of us assuming that signed implies notarized.

The same day, the v1.0.0 release died at “missing updater signature(s)” (commit ccdded8, 2026-05-10). Tauri emitted both architectures’ update bundles under the identical name “Memoire Studio.app.tar.gz”, and the second mv in the workflow silently overwrote the first. The latest.json generation step then found one tarball instead of two, and the auto-updater was broken for whichever architecture lost the race. Per-arch renames fixed it.

Seventeen days later the macOS signing workflow broke again, and v1.0.3 exists mostly as that repair (commit 80ae5a2, 2026-05-27). One of our four published Studio versions is, honestly described, a release-engineering patch.

The checklist those failures produced

“Good to go” now means every item below passes, and each is on the list because skipping it burned us once:

  1. npm resolves the expected latest with the right binary, README, and MCP server name.
  2. The GitHub release on sarveshsea/memi-studio carries signed, notarized, stapled DMGs for both arches, plus SHA256SUMS.
  3. latest.json lists both architectures, one filename per arch.
  4. brew install --cask sarveshsea/memi/memi-studio installs the same Studio version the release page shows.
  5. The website download button points at the current DMG. The site’s release.ts is the single source of truth and currently resolves to Memoire.Studio_1.0.4_aarch64.dmg plus its checksum file.
  6. A live Codex or Claude Code session completes from the installed build, because an app that launches but cannot run an agent has not actually shipped.

None of this is clever. All of it is specific, which is the point.

Metadata sync is a process bug, not a chore

Three separate commits exist purely to keep public metadata truthful: “align runtime public metadata” (374bc81, 2026-05-26), “sync cli metadata and default launch state” (351001c, 2026-05-26), and “sync public package metadata” (284f3e1, 2026-06-06). The website repeated the same dance for every Studio tag: download copy moved to 1.0.1 on 2026-05-14, to 1.0.3 on 2026-05-27, and to 1.0.4 on 2026-06-07, each as its own commit.

I read that list two ways. The flattering way: we kept the surfaces truthful, and the commits prove it. The uncomfortable way: every manual sync commit is evidence that the release process has a hole where automation should be. Three of them in two weeks means the hole is real. The audit covers for it today; the durable fix is generating those surfaces from one release manifest instead of editing them in lockstep by hand.

The part nobody sees until it breaks

The audit has an ops backbone in docs/CREDENTIALS.md: a table of nine secrets, which release step each one breaks, and a rotation calendar. The Developer ID certificate expiry is recorded as 2031-05-08. The file also captures the failure mode that would otherwise cost a future day of debugging: changing the Apple ID password silently breaks notarization.

Writing that down felt like overkill in May, when there were two surfaces and a handful of secrets. By June, with four surfaces and nine secrets, it is the only reason the audit is repeatable by a version of us that has forgotten everything in this post.

The habit

Every public release now leaves a small audit artifact behind: which versions shipped, which checks passed, what was intentionally not changed, and where downloads point. Not because process is a virtue, but because all four surfaces have drifted at least once, and a written audit is cheaper than discovering the third silent regression from a user’s bug report.