Skip to content

fix(release): restart gateway after app replacement - #106

Closed
tcballard wants to merge 6 commits into
mainfrom
codex/restart-gateway-after-app-replacement
Closed

fix(release): restart gateway after app replacement#106
tcballard wants to merge 6 commits into
mainfrom
codex/restart-gateway-after-app-replacement

Conversation

@tcballard

@tcballard tcballard commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements WF-ROADMAP-0015 desktop v0.1.0 app-replacement recovery.

Adds:

  • one-time bundled-gateway reconciliation after the containing app is replaced;
  • fixed bundle-relative path and installation-fingerprint checks before restart;
  • deterministic changed, unchanged, mismatch, stopped, uninstalled, and restart-failure coverage.

Scope

Included

  • Detect a changed installed app before the initial gateway health/readiness refresh.
  • Restart only a loaded LaunchAgent that points at the exact bundled Rust gateway path.
  • Persist the installation fingerprint only after a successful restart.

Excluded

  • Provider, credential, routing-policy, or default-destination changes.
  • Automatic update support or replacement of the existing manual update/rollback contract.
  • Repairing a LaunchAgent that points at an external or mismatched gateway.

Product / Architecture Decisions

  • A loaded launchd process can retain the executable image and signing context from the app it was launched under even after /Applications/Wayfinder.app is replaced at the same path.
  • The app fingerprint combines desktop version/build, verified signing-Team state, and bundled-helper file metadata. It is an optimization marker, not a trust decision.
  • The reconciler locates only the fixed bundle-relative helper and requires the exact LaunchAgent executable path; full bundled-helper authentication still occurs at each execution boundary.
  • Reconciliation runs before the initial setup and gateway status refresh so Apple Foundation Models readiness is not computed through a stale process.
  • Failure is fail-closed and retryable: no marker is stored after locator, status, path, or restart failure.

User-Facing Contract

CLI

No CLI changes.

Human Output

Replacing Wayfinder and reopening it automatically refreshes the persistent bundled gateway. Users should not need to run launchctl kickstart to restore Apple Foundation Models availability.

JSON Output

No JSON changes.

Exit Codes

No exit-code changes.

Verification

Ran

env CLANG_MODULE_CACHE_PATH=/private/tmp/wayfinder-replacement-module-cache SWIFTPM_MODULECACHE_OVERRIDE=/private/tmp/wayfinder-replacement-module-cache WAYFINDER_DISABLE_SWIFTPM_SANDBOX=1 swift test --disable-sandbox --scratch-path /private/tmp/wayfinder-replacement-build --package-path macos/WayfinderMac

git diff --check

Covered

  • All 171 Swift tests passed.
  • Changed matching installations restart once and persist the new marker.
  • Unchanged installations do not query or restart launchd.
  • External/mismatched, stopped, and uninstalled services defer without mutation.
  • Failed restarts remain retryable and never persist success.
  • A Developer ID-signed replacement changed the live gateway PID from 23749 to 48559 and persisted the new 0.1.0|1|R8HXTBY3NM|... fingerprint.
  • The restarted gateway reported {"status":"ok","models":["apple-local"],"offline":true} and returned OK. from a real non-streaming apple-local request.
  • The first signed acceptance build exposed a release-only Swift concurrency crash in async helper verification during launch. The final implementation removes async execution from replacement detection; the corrected signed build remained running and passed the same end-to-end check.

Review Path

  1. GatewayReplacementReconciler.swift for fingerprint, trust, and retry behavior.
  2. WayfinderMacApp.swift for startup ordering.
  3. GatewayReplacementReconcilerTests.swift for boundary coverage.

Notes For Reviewer

The bug was reproduced on a real signed/notarized RC: the live Foundation Models harness reported available, while the stale pre-replacement gateway returned wayfinder_router_not_ready. A manual launchd restart immediately restored a successful apple-local reply. The corrected branch was then Developer ID-signed and installed over the stale process; automatic reconciliation restarted the gateway and restored the same successful Apple reply without manual launchctl work.

@tcballard
tcballard marked this pull request as ready for review July 19, 2026 21:55

Copy link
Copy Markdown
Contributor Author

Closing: this branch's content is already on main, and it can no longer be merged.

Why it can't merge

main and codex/restart-gateway-after-app-replacement share no common ancestor. main's history was rebuilt during the Rust-only migration — its root is b9b65ed with 58 commits total, while this branch descends from the original scaffold root 47e93ab. There's no merge base, so GitHub reports dirty and neither rebase nor merge is possible without --allow-unrelated-histories, which would conflict on every file.

Why it doesn't need to

Comparing this branch's tip (a73f26d) against main file by file, 9 of the 17 changed files are byte-identical on main — the content came across during the rebuild, it just can't be proven by ancestry:

Note that #108 and #109 merged into this branch rather than into main, which is why the branch tip carries content main appeared to be missing.

One loose end

CodexAccountClient.swift on main still returns the older 404 copy:

"ChatGPT account routing is not configured. Add a codex-app-server model to the gateway first."

#109 replaced it with "ChatGPT has not been added to this gateway yet." That replacement was written for the manual-guidance flow, and main's auto-configure path rarely surfaces the string at all, so it isn't being carried over as-is. Worth a small standalone copy pass if the wording still reads too implementation-flavored.

Nothing else from this branch is outstanding.


Generated by Claude Code

@tcballard tcballard closed this Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant