Migrate from 0.54 to 0.55
Breaking changes and a verification checklist for upgrading a production Murasaki app.
Murasaki 0.55 hardens runtime authority, updates, packaging, and browser-data identity. Most applications compile without structural changes, but the items below are deliberate fail-closed changes. Apply them before publishing an updated desktop build.
1. Rename renderer environment variables
Use MURASAKI_PUBLIC_* for values that may be embedded in renderer JavaScript:
MURASAKI_PUBLIC_API_ORIGIN=https://api.example.com
DATABASE_URL=postgresql://localhost/privateOnly the first value is renderer-visible. Keep credentials unprefixed. If an
existing application owns another public prefix, add it explicitly with
build.envPrefix; do not expose the empty prefix.
2. Add generatedAt to update manifests
Fresh manifests created by murasaki release --manifest already include
generatedAt. A legacy manifest without it is rejected in production by
default. During a bounded migration only, you may set:
updater: {
allowLegacyManifestsWithoutGeneratedAt: true,
}Remove the flag after every supported installed version can consume a current manifest. 0.55 also persists the highest authenticated timestamp and version; publishing an older signed manifest is treated as replay/rollback.
3. Declare executable resources
Sidecars and helper binaries need the structured resource form:
bundle: {
resources: [
{ from: 'bin/helper', to: 'sidecars/helper', executable: true },
],
}This makes Murasaki sign the helper before sealing the app/installer. An undeclared Mach-O, PE, ELF, or shebang resource now stops packaging instead of producing an artifact that Gatekeeper or Windows policy rejects later.
4. Keep the persisted app origin available
0.55 selects and stores one loopback port on first packaged launch. Later launches fail if that port is occupied rather than moving to another origin and making localStorage/IndexedDB appear empty. Avoid binding unrelated local services to the application's persisted port. If startup reports a collision, stop the conflicting process; deleting the origin state intentionally creates a new browser-data identity and is not a normal recovery step.
5. Review capability boundaries
- Native APIs and Node Main/API routes are separate default-deny surfaces.
- Declare renderer native grants in
capabilitiesand Node/API grants inbackendCapabilities, preferably per window. - Camera, microphone, and geolocation browser APIs are denied by the framework response policy. Use an app-owned native flow when those features are added; do not weaken the header globally without defining an equivalent boundary.
sign.appSandbox: trueis rejected. Use Hardened Runtime + notarization on macOS until Murasaki documents a sandbox-compatible Node helper model.
6. Verify the release on real targets
Run at least:
pnpm typecheck
pnpm test
pnpm exec murasaki build
pnpm exec murasaki bundle --target <platform-arch>
pnpm exec murasaki installer --target <platform-arch> --signOn macOS, verify codesign, Gatekeeper, and the stapled notarization ticket. On Windows, verify Authenticode and launch the installed application with security controls enabled. Never make disabling Gatekeeper, SmartScreen, or Smart App Control part of the user installation path.