Imported from ManagementMO/wakelease (
AGENTS.md). Install upstream withnpx skills add ManagementMO/wakelease. Copyright stays with the author.
WakeLease engineering rules
Lineage
Read UPSTREAM.md. The repository preserves Adrafinil v1.7.0 history. Do not erase upstream MIT notices or misrepresent inherited systems work. Source directory names are intentionally retained during the lease refactor.
Safety
Never run the real helper, register launch services, install agent hooks into the developer's home, change pmset, or put the host to sleep as part of automated tests. Use fake power controllers and temporary home directories. A physical closed-lid test needs explicit approval and a documented recovery procedure.
Production authorization must fail closed. Unsigned development must not weaken the root helper's caller checks. No telemetry or automatic network activity in ordinary operation. Do not log user reasons, command lines, repository paths, or hook payloads.
Verification
- Upstream shared package:
swift test --package-path AdrafinilShared(full Xcode includes Swift Testing). - Root command-line build:
swift build. - On Command Line Tools installations without the Testing module:
WAKELEASE_SOURCE_TESTING=1 swift test --scratch-path .build/source-testing --disable-xctest --disable-experimental-prebuilts. This opt-in builds pinned Swift Testing 6.2.4 and SwiftSyntax 602.0.0 for tests only; they are not product dependencies. Keep a separate scratch directory to avoid stale macro modules after changing SwiftSyntax versions. - Initial baseline: 416 tests in 41 suites passed with that command on macOS 26.6.2 (25G83) / Apple Swift 6.3.3; CLI, daemon, and helper also compiled. No real power operations were executed.
- Full Xcode app build is a separate verification gate; Command Line Tools cannot perform it.
- End-to-end CLI tests:
python3 Tests/cli_integration.py. They launch only the explicitly labeled simulation daemon in a temporary private directory and test TTY/signals, concurrent clients, TTL, and restart.WAKELEASE_BIN_DIRmay select a different built binary directory. - SwiftSyntax is intentionally a direct test-only dependency to pin the transitive macro version; SwiftPM may warn that no target imports it directly.
- Native UI build:
WAKELEASE_SOURCE_TESTING=1 swift build --scratch-path .build/source-testing --disable-experimental-prebuilts --product WakeLeaseMenu. The distinct executable name avoids a case-insensitive collision withwakelease; packaging puts the app executable and CLI in different bundle directories. - On a logged-in macOS desktop,
python3 Tests/ui_smoke.pyrenders isolated preview windows and checks they exit. Preview mode never connects to the daemon or installs services. Keep menu insertion updates idempotent: writing unchanged values into the observable preferences produced a SwiftUI menu-graph loop, diagnosed withsampleand covered by this smoke test. - With source Swift Testing 6.2.4, evaluate mutating value-type method calls before
#expect; direct calls may trigger the macro's immutable-receiver expansion. - Packaging:
python3 Tests/package_smoke.pyverifies a disposable ad-hoc bundle, version commands, preview rendering and production-mode refusal.WAKELEASE_HEADLESS=1skips only its GUI render when no logged-in desktop exists. python3 Scripts/lint.pyuses checksum-pinned SwiftFormat 0.63.0 / SwiftLint 0.65.1. SourceKitten excludes Command Line Tools discovery by default; the script suppliesXCODE_DEFAULT_TOOLCHAIN_OVERRIDEonly when that toolchain's framework exists. No global developer-directory setting or lint rule is changed.python3 Tests/release_tools.pyandpython3 Scripts/check-repository.pycover release-input validation, local doc links, identities, legal notice and asset geometry.Tests/root_removal_smoke.pyis opt-in on disposable CI runners only (CI=true,WAKELEASE_ROOT_FIXTURE=1). It usesWakeLeaseRemovalProbesolely to create/delete a root-owned temporary ticket and prove unprivileged read/delete but not write/create permissions. Never enable it against real helper state or as a local privileged power test.- Same-user install/removal share a stable
maintenance.lock; do not unlink a live lock inode. Global removal is separately fenced by the helper and survives helper restart. Release held file locks withSecureDirectory.closeLock, not bareclose: descriptor references inherited during concurrent subprocess creation can retain a BSD flock after the parent closes its descriptor. The duplicated-descriptor regression covers this. python3 Tests/idle_smoke.pymeasures the owned simulation daemon with the same Mach timebase conversion used byProcessResolver; do not divide task-info CPU counters by 1e9 directly on Apple Silicon.- Generated plugin execution tests require Node 22.19+.
python3 Scripts/install-host-fixtures.pyinstalls only checksum-pinned, script-disabled Pi test dependencies under.build/pi-host;python3 Tests/pi_host_smoke.pyuses a clean home, mocked model and network denial, never real user credentials or paid calls. - Keep Xcode project object/preferred format at 77: format 100 was rejected before compilation by the Intel/macOS 15 runner's Xcode 26.3. Existing filesystem-synchronized objects work in 77; changing format must not change deployment or signing settings.
- The CI matrix runs full Xcode builds, core/CLI/host execution and package checks on
macos-26andmacos-15-intel. These standard public runners do not certify physical MacBook sleep or production signing. WAKELEASE_REQUIRE_UI_AUDIT=1 python3 Tests/ui_smoke.pyrequires native AX/keyboard checks using already-granted Accessibility permission. The auditor verifies the child executable, targets only its PID, and uses--preview-pasteboard wakelease-ui-test-<uuid>to avoid the general clipboard. Without existing permission the optional audit skips; it must never request permission automatically. Native labels may be linked throughAXTitleUIElement, not stored directly on the control.Tests/xpc_smoke.pyruns an explicitly ad-hoc-signed copy ofWakeLeaseXPCProbethrough five anonymous-XPC cases in three fresh processes. Build it with the source-testing opt-in. SwiftPM unit tests execute inside a toolchain helper, not their test bundle, so its signature is not a portable fixture; never re-sign the toolchain. Await XPC replies rather than blocking the executor, and explicitly type error callbacks@Sendable. Listener pins reject before delegate admission; client pins reject incoming replies, so retain the read-only version probe and peer-identity check before mutation. This is not production-certificate acceptance.- Pi SDK fixtures cover eight lifecycle scenarios.
session.isStreamingstays true during retry backoff; the real Pi reload UI therefore rejects a reload while that work remains active. Do not invent a reload race by substituting the lower-level agent streaming flag. - Inspect
git diff --checkand run relevant tests before each commit.
Keep the actor registry as the source of truth. Count effective leases, not process names or UI state. Check stale generations after every suspension point on the sleep-release path. A failed unblock must remain observable and retryable.