feat: prepare Night Walker for friend distribution - #1
Closed
ItsFlow wants to merge 5 commits into
Closed
Conversation
added 5 commits
August 19, 2026 23:49
Public name is Night Walker; bundle id stays com.flo.color-filter-scheduler so the captain's prefs and login item are not orphaned. Packaging: bundle.sh now lipo-creates a universal ad-hoc-signed dist/Night Walker.app; dmg.sh writes dist/NightWalker-<version>.dmg. install.sh/uninstall.sh target Night Walker.app and refuse to hijack a side-by-side Color Filter Scheduler.app. Security: CLI fail-closed on NaN/Inf/out-of-range coords and intensity; --render-panel stays under cwd (symlinks resolved) and does not write Settings; LaunchAgent paths go through PlistBuddy. Tests: tests/run.sh is the single local/CI entry (solar fixtures, --decide/--selftest, CLI restore, hygiene, bundle/codesign). GitHub Actions runs the headless suite on macos-latest. Proof: RUN_BUNDLE=0 tests/run.sh exit 0; bundle-contract lipo x86_64+arm64 and codesign --verify; Color Filters and captain prefs restored exactly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Make Night Walker production-ready for friend distribution, then ship a green PR via no-mistakes against the existing public repo https://github.com/ItsFlow/night-walker (do not create another repository). Branch fm/cfs-prodready. Firstmate owns merge.
Product name is Night Walker. Keep executable/package name color-filter-scheduler. Keep bundle id com.flo.color-filter-scheduler (historical; changing it would orphan the captain's prefs and login item). User-facing name, DMG, README, and menu-bar panel title are Night Walker.
Hard safety on the captain's live Mac: do not install over ~/Applications/Color Filter Scheduler.app, rewrite the LaunchAgent, or write com.flo.color-filter-scheduler UserDefaults. Do not leave Color Filters changed. Negative lat/lon cannot be passed via NSArgumentDomain. Do not change MediaAccessibility SPI signatures (CMediaAccessibility.h), solar math formula, or persisted config keys. CLT only, no Xcode, no third-party deps. Do not notarize or request Apple Developer credentials; ad-hoc sign and document Gatekeeper.
Ship: security + stability tests that actually run (solar fixtures, polar day/night, longitude-near-UTC-day-boundary, reconcile/decide, CLI read-only vs mutate-with-restore, bundle codesign, universal lipo, repo hygiene) via tests/run.sh; security hardening without inventing a TCC helper or notarization flow; honest residual risk (ad-hoc signature, private Color Filters SPI, not App Store); universal .app via bundle.sh and friend-ready dist/NightWalker-.dmg; GitHub Actions on macos-latest (skip GUI-only steps). Do not open a GitHub Release until CI is green.
Captain 2026-08-19: never launch Claude. For any review or no-mistakes pipeline agent use Codex only. Do not spend Claude quota.
Delivery is no-mistakes to a green PR against origin main. Do not merge. Do not push to the default branch.
What Changed
SMAppServicelogin-item registration, plus guarded install and uninstall behavior.Risk Assessment
Testing
Targeted debug, scheduler, safety, rendered-UI, universal bundle, codesign, and mounted-DMG checks all passed; reviewer-visible evidence was captured externally, live Color Filters remained unchanged, and generated worktree artifacts were cleaned up.
/var/folders/16/p22jkpcn0z10z3lrwkpc4yq00000gn/T/no-mistakes-evidence/01M0E3GXTNQJ55PW3M74JBRENA/panel-front-running.png)/var/folders/16/p22jkpcn0z10z3lrwkpc4yq00000gn/T/no-mistakes-evidence/01M0E3GXTNQJ55PW3M74JBRENA/panel-settings.png)Evidence: Scheduling and live-state safety transcript
Evidence: Mounted DMG inspection
Evidence: Universal bundle contract
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed (3) ✅
tests/ui-contract.sh:45- The newly added panel-title checks only grep Swift source, so they can pass for dead/commented text and violate the explicit test-quality rule. The surrounding panel-contract test uses the same source-content-only pattern. Replace these with observable UI/public-interface checks or remove them; similarly, bundle-contract.sh should require both architectures directly fromlipooutput instead of deciding whether universality is required by grepping bundle.sh.🔧 Fix: Replace source-grep contracts with runtime checks
2 errors still open:
tests/cli-contract.sh:221- The required “CLI read-only vs mutate-with-restore” test does not actually run on a clean machine: when the original Color Filters preferences are absent—as expected on GitHub-hosted runners—the successful--set-enabledand--reconcile --applypaths are skipped and the suite still passes. Decide whether this acceptance criterion must run in CI or is explicitly allowed to be a captain-only conditional test; if it must run, provide a recoverable isolated mutation strategy that restores the initially absent state.README.md:23- The friend installation flow only copies the app from the DMG and never registers it to launch at login. After logout or reboot, the menu-bar process—and therefore its five-minute/wake reconciliation—will not run until the friend manually opens it again, despite the instructions presenting Automatic as an ongoing sunset/sunrise scheduler. Confirm whether friends are expected to reopen it each session; otherwise add a supported login-item flow (or explicit Login Items setup instructions) at the distribution boundary.🔧 Fix: Register Night Walker as login item
1 error still open:
Sources/color-filter-scheduler/AppDelegate.swift:71- Two launch-at-login owners now compete:install.shstarts the bundled executable through a LaunchAgent, then this startup path also registersSMAppService.mainApp. If registration succeeds, subsequent logins can launch two app processes, producing duplicate menu items and competing reconciliation. Choose one mechanism at the shared installation boundary—preferably migrateinstall.shto SMAppService—or explicitly detect the managed LaunchAgent before registering.🔧 Fix: Unify login lifecycle under SMAppService
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
swift build.build/.../color-filter-scheduler --selftestDeterministic--decide --now ...checks for Munich daylight/darkness, 80°N polar day/night, and Tokyo near the UTC-day boundaryCompared live Color Filter enabled, intensity, and type values before and after read-only CLI decisions.build/.../color-filter-scheduler --render-panel .build/panel-evidence-$PPID; visually inspected running and settings PNGsbash tests/bundle-contract.sh./dmg.shMounteddist/NightWalker-1.0.0.dmgread-only and inspected its app name, Applications link, bundle identifier, x86_64/arm64 executable, and code signatureDetached the DMG and removed all generated worktree packaging/render artifacts✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.