|
| 1 | +# Intel macOS 13.5 Validation |
| 2 | + |
| 3 | +This fork supports source installation on Intel Macs running macOS 13.5 or later with Xcode 15 and Swift 5.9. |
| 4 | + |
| 5 | +## Automated checks |
| 6 | + |
| 7 | +Run from the repository root: |
| 8 | + |
| 9 | +```sh |
| 10 | +swift --version |
| 11 | +xcodebuild -version |
| 12 | +swift build -c release |
| 13 | +swift test |
| 14 | +./scripts/test-install-lifecycle.sh |
| 15 | +SKIP_SIGNING=true ./scripts/build-pkg.sh "$TMPDIR/capsomnia-pkg" |
| 16 | +``` |
| 17 | + |
| 18 | +Both release executables must be x86_64 and declare a 13.5 deployment target: |
| 19 | + |
| 20 | +```sh |
| 21 | +file .build/release/Capsomnia .build/release/capsomnia-pmset |
| 22 | +otool -l .build/release/Capsomnia | grep -A3 LC_BUILD_VERSION |
| 23 | +otool -l .build/release/capsomnia-pmset | grep -A3 LC_BUILD_VERSION |
| 24 | +``` |
| 25 | + |
| 26 | +## Source-install ownership |
| 27 | + |
| 28 | +The source installer owns only `~/Applications/Capsomnia.app`, the user LaunchAgent, and shared privileged files proven by its root-owned receipt. It refuses to overwrite package-owned, foreign, symlinked, or otherwise unproven state. The package installation under `/Applications` and its system LaunchAgent remain package-owned. |
| 29 | + |
| 30 | +Installation uses a root-owned transaction journal. A failure before commit restores the recorded pre-state and normal sleep. If rollback or sleep-state verification cannot be proven, the command exits nonzero and retains the journal as recovery evidence. |
| 31 | +Install and uninstall operations share a root-owned lifecycle lock. Uninstall snapshots every managed asset and restores the complete pre-state if any deletion fails, leaving recovery evidence when rollback cannot be verified. |
| 32 | + |
| 33 | +Package installs write `/Library/Application Support/Capsomnia/package-install.receipt`, which binds the package app, system LaunchAgent, helper, and sudoers rule. Package preinstall refuses a source receipt and refuses any existing managed target unless every target still matches that package receipt. Before payload replacement, preinstall snapshots every package-owned asset. If activation fails, postinstall restores the complete prior payload, sudoers rule, receipt, and console-user runtime state; unverifiable rollback retains the snapshot as recovery evidence. The new receipt is committed only after LaunchAgent verification. Neither package install nor uninstall removes unreceipted legacy paths. The bundled uninstaller applies the same collision, symlink, foreign-file, and provenance-drift checks. |
| 34 | + |
| 35 | +## Manual Intel hardware checklist |
| 36 | + |
| 37 | +1. Confirm `uname -m` is `x86_64` and macOS is 13.5 or later. |
| 38 | +2. Run `./scripts/install.sh` and supply administrator credentials. |
| 39 | +3. Confirm the app starts from `~/Applications/Capsomnia.app` and its LaunchAgent is loaded and running. |
| 40 | +4. Turn Caps Lock on and verify the menu-bar active indicator and `pmset -g` `SleepDisabled 1` agree. |
| 41 | +5. Turn Caps Lock off and verify `SleepDisabled 0`. |
| 42 | +6. Run `swift test` to cover shortcut handling, all-caps prevention, Accessibility failure behavior, and settings persistence regressions. |
| 43 | +7. With safe power and ventilation, verify closed-lid behavior with and without an external display. |
| 44 | +8. Quit or uninstall the app and verify normal sleep is restored. |
| 45 | +9. Run the lifecycle harness to verify same-owner reinstall/update, settings preservation, and ownership validation. |
| 46 | +10. Run the bundled source uninstaller and verify `SleepDisabled 0`; confirm package-owned paths are untouched. |
| 47 | + |
| 48 | +Do not mark a release compatible until every automated check and applicable hardware item passes on an Intel Mac. |
| 49 | +## Recovery evidence |
| 50 | + |
| 51 | +Source installations use receipt format v3 at `/Library/Application Support/Capsomnia/source-install.receipt`. The receipt binds each managed path, its ownership and mode, the full app-tree hash, and the transaction identifier. Transaction journals are stored under `/Library/Application Support/Capsomnia/transactions/<transaction-id>`. |
| 52 | + |
| 53 | +A successful rollback removes its journal. An unsafe terminal state leaves the journal in place with a `rollback-unverified` marker and exits nonzero. Do not delete that evidence until the machine state has been inspected and restored. To force normal sleep during manual recovery, run: |
| 54 | + |
| 55 | +```sh |
| 56 | +sudo pmset -a disablesleep 0 |
| 57 | +pmset -g | grep SleepDisabled |
| 58 | +``` |
| 59 | + |
| 60 | +Confirm the second command reports `SleepDisabled 0`, inspect the retained snapshots and state markers, and restore the affected paths from the journal before removing it. Unsafe uninstall rollback prints its recovery ID, retained journal path, and deterministic recovery procedure. The source uninstaller removes shared assets only when the v3 receipt still proves ownership; provenance drift requires manual inspection rather than destructive cleanup. |
| 61 | + |
| 62 | +Source builds are unsigned. macOS may require an explicit local trust decision, and this fork does not claim upstream signing or notarization. |
0 commit comments