Deliver macOS App and Push
Treat a source edit as unfinished until the tested Release app is installed at the documented stable path. Treat explicit publication authority from the opening request as durable for the scoped task.
Establish the completion contract
At the beginning of the task:
- Read every applicable
AGENTS.mdand project instruction file. - Inspect the worktree before editing; preserve unrelated user changes.
- Determine the required test command, Release build command, built app path, stable delivery app path, bundle identifier, remote, and branch.
- Record whether the user already requested
commit,push,publish,GitHub, orPRwork. Setpush_authorized = truewhen the opening request explicitly includes a normal push or PR. - Do not ask the user to reconfirm an already-authorized normal commit or push later in the task.
Only ask when a material choice cannot be discovered safely, such as multiple plausible destination apps or remotes. Do not ask merely because execution has reached the push step.
Complete every macOS code change
After changing Swift source, resources, tests, build configuration, or app behavior:
Close the existing stable app before testing/building:
zsh /absolute/path/to/scripts/close-macos-app --app "/absolute/path/App.app"Run this with process/WindowServer escalation when the restricted shell cannot see GUI processes. Match only the exact bundle identifier or executable path; never use a broad
pkill -fpattern.Run the project-required tests. Fix failures and rerun until successful unless an external blocker is proven.
Run the project Release build command.
swift buildalone is not app delivery unless the project explicitly defines it that way.Ensure the fresh app occupies the documented stable path. If the build output differs from the stable path, replace it with:
python3 /absolute/path/to/scripts/replace_macos_app.py \ --source "/absolute/build/Result.app" \ --destination "/absolute/stable/App.app"The helper closes the old bundle, stages a complete copy, verifies it, swaps it into place, rolls back on failure, and removes the verified backup. Use
--allow-unsignedonly when the project intentionally produces unsigned local apps.If the build already writes directly to the stable path, run the replacement helper with identical source and destination paths; it closes the app and validates the bundle without copying.
Verify
Info.plist, the bundle executable, code signature, source/destination fingerprints, and that no stale app process remains.Do not relaunch the app unless the user or the test plan requests it.
Prefer a project-supplied build/install script when it demonstrably performs these gates. Still verify the final stable app path; never assume a successful compile replaced the user-facing app.
Read references/macos-build-delivery.md when discovering commands or when build output and delivery paths differ.
Commit and push without redundant confirmation
When push_authorized = true:
- Review the final diff and exclude unrelated worktree changes.
- Run all delivery gates before committing.
- Commit only the scoped files.
- Push the current scoped branch with a normal non-force push, setting upstream when needed.
- Open or update a PR only when the opening request included PR work.
- Invoke any mandatory tool approval directly. Do not add a conversational “shall I push?” checkpoint.
Initial authorization does not permit force-push, history rewriting, branch/tag deletion, bypassing branch protection, publishing secrets, changing repository/remote, or including unrelated user changes. Request separate authority for those operations.
If publication was not requested, do not infer commit or push authority from the build request. Stop after verified app delivery and report the worktree state.
Diagnose GitHub access correctly
Read references/github-auth-and-push.md before declaring any GitHub credential invalid.
Run the non-secret probe from the repository:
python3 /absolute/path/to/scripts/github_access_probe.py --repo /absolute/repository
If it reports network_or_sandbox, rerun that same command once with network escalation. Do not switch to login/logout commands.
Use the same login-shell environment in which the user's terminal credentials are available. Distinguish:
- sandbox/network/DNS failure;
- HTTPS credential-helper failure;
- SSH key or agent failure;
- wrong remote or repository permission;
- actual GitHub CLI token rejection.
If a command fails because network access is restricted, rerun it once with the tool's network escalation. Do not tell the user to reauthorize GitHub until direct API authentication fails outside the restricted network context. gh auth status alone is not proof: it can label a token invalid when a proxy connection is sandbox-blocked. Never print tokens or run commands that expose them.
Completion gate
Do not claim completion until all applicable items are true:
- required tests passed;
- Release build passed;
- the exact old app was closed;
- the stable
.apppath contains the fresh verified build; - signing and bundle checks passed, or intentional unsigned status was reported;
- a scoped commit exists when commit or publication was requested;
- an authorized push completed and upstream/PR state was verified when publication was requested;
- final response lists commands, results, app path, commit, branch, and push result.
When blocked, report the exact command, classified cause, and next required state. Do not substitute a source-only success, stale app bundle, repeated confirmation, or unsupported “token expired” claim.