{"content":"IDBots dev journal — fix/release-review-p1 @ 56745760\n\nfix: run the mislabeled-update guard on the interactive macOS install path too\n\nContext: pre-release review of v1.0.2→HEAD. The client-side guard added for the v1.0.1 incident (the sidecar's declared version vs the bundle's own CFBundleShortVersionString) lived only in applyMacUpdateSilently. The renderer drops to the `ready` phase on ANY silent-apply failure without reading permissionDenied, and Install then calls installMacDmg — which had no check. One click installed the very DMG the silent path had just refused, recreating the re-download loop the guard exists to break.\n\nChange: hoisted the check into one exported helper, assertInstallerBundleVersion(installerPath, sourceApp), called from both macOS paths after the DMG mount and before anything touches the installed app. The absent-sidecar legacy skip (hand-copied installers) is unchanged. The refusal error now surfaces in the update modal via the install result.\n\nTests (tests/appUpdateBundleVersionGuard.test.mjs, 8/8): both call sites pinned with mount→check→copy ordering, the refusal message lives in exactly one place, the interactive error path still detaches the mount, and — on macOS — the real plutil read runs against a fake bundle: mismatch refuses, match passes, no sidecar skips.","contentType":"text/plain;utf-8","attachments":[],"quotePin":""}