Skip to content

Recovery launcher: land #142 - #154

Merged
krishhgg merged 11 commits into
mainfrom
integration/recovery-launcher
Nov 9, 2026
Merged

krishhgg merged 11 commits into
mainfrom
integration/recovery-launcher

Conversation

@krishhgg

@krishhgg krishhgg commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Login Items now shows Insomnia, not an unnamed shell script. The recovery agent that undoes an abandoned session runs a small native launcher inside the app, pinned by its code signature, which checks the bundle and then runs the sealed backstop script.

This lands #142 by @ilya-the-frog at bf8a75a. The commit is merged here unchanged, so GitHub marks #142 merged when this one merges and its author keeps the credit. #142 conflicts with #146 (the session command line), which lands first, so it can't merge as it is.

To @ilya-the-frog: please don't push to your branch now. A new commit on it isn't in this pull request, so #142 would stay open instead of showing as merged.

The base is integration/wave1-base: main with #146 and #147 (which carry #145) merged, as main will be once they land. When #147 merges, this pull request's base changes to main and nothing else changes.

Conflicts resolved

Maintainer commits

  • 38b0ef6: the packaging tests run the intact, edited-script and wrong-build cases through the shell verifier as well as the native command. The plist still falls back to the shell verifier for an older bundle, a requirement without cdhashes and SIP that is not known to be enabled, and install.sh writes the same fallback, but since Show Insomnia in Login Items with a pinned native recovery launcher #142 no test ran it. Breaking the verifier three ways (no requirement check, exit 0 on refusal, no verification) fails the new run.

Tests

The full suite at this head, 38b0ef6: 1408 tests, 0 failures, on macOS 26.2 on the maintainer's MacBook. Hosted CI runs on macOS 26 and 27.

Review

The merge is clean at 0981a6a, the same tree as f0f183e; only commit messages changed. That review checked the command order in main.swift, that an install, an interrupted install or an uninstall cannot leave the recovery agent running something unpinned, and that the release checklist still covers Login Items, the launcher's spawn constraint and recovery after a restart. 38b0ef6 had its own review with no findings: the shell run executes the exact ProgramArguments the plist writes, and it checks what main's test checked before #142.

Evidence

To run on the owner's MacBook at the final head: install, Login Items shows Insomnia, the recovery agent's launcher carries the expected spawn constraint, and after one restart the agent runs and recovers a session journal.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable issue was found.

Summary

The recovery agent can now start Insomnia --backstop, letting Login Items identify the app instead of a shell.

  • Insomnia's --backstop command checks the bundle before recovery.
  • The recovery agent appears as Insomnia when launchd can pin it.

The earlier unnumbered shell-coverage finding is addressed. Following krishhgg’s fix, the shared cases check intact bundles, edited scripts and wrong builds through both launchers. No new actionable issue was found. macOS tests and hardware checks were not run in this review.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Choose recovery launcher] --> B{Native command, cdhashes and SIP enabled?}
    B -->|Yes| C[launchd checks executable hash]
    C --> D[Insomnia --backstop checks bundle]
    B -->|No| E[Shell verifier checks bundle]
    D --> F{Bundle passes?}
    E --> F
    F -->|Yes| G[Execute sealed backstop.sh]
    F -->|No| H[Log refusal and exit]
Loading

Reviews (4) · Last reviewed commit: "Merge main into recovery-launcher" · Reviewed by Greptile

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T04:24:50.004272Z 89a5f33 Draft marked ready
🔒 Security Review ✅ Completed 2026-11-09T04:26:57.171024Z 89a5f33 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Since the native --backstop command landed, runAgent only ran that
command, so no test executed LaunchdBackstop.agentProgram any more. The
plist still uses that shell verifier for an older bundle, a requirement
without cdhashes and SIP that is not known to be enabled, and install.sh
writes the same fallback. Its remaining tests only read the program text
or the plist.

The intact, edited-script and wrong-build cases now live in one helper
that runs twice: once with the native command, as before, and once with
the ProgramArguments plistDictionary writes for a target without a native
executable, run with HOME in the scratch tree. The shell run checks the
exit status, whether the sealed script ran, and the one-line refusal in
~/Library/Logs/Insomnia/insomnia.log with codesign's reason, as main's
test did. The native assertions are unchanged.

Checked by breaking agentProgram three ways and running the shell test:
dropping the -R requirement fails it 4 times (the wrong build runs the
script, exits 0 and logs nothing), exiting 0 on refusal fails it 2
times, and skipping verification fails it 3 times. The native test
passed with the requirement dropped. swift build and swift test --filter
PackagingTests pass, 29 tests, 0 failures.
@krishhgg

Copy link
Copy Markdown
Owner Author

The full suite at 38b0ef6, this head, passes on macOS 26.2 on the maintainer's MacBook: 1408 tests, 0 failures, in 31 minutes.

A run in a macOS 27.0.1 VM with SIP disabled installed the external
shell verifier, as designed, and Login Items listed the recovery agent
as sh with a generic icon. Only the native plist carries
AssociatedBundleIdentifiers, so the Insomnia name and icon come with
SIP enabled. install.md and the release check now say so, so a tester
on a Mac with SIP off doesn't read the sh row as a failed upgrade.
krishhgg added a commit that referenced this pull request Nov 7, 2026
@krishhgg

krishhgg commented Nov 7, 2026

Copy link
Copy Markdown
Owner Author

VM evidence at 38b0ef6: the recovery agent with SIP disabled

A macOS 27.0.1 VM with System Integrity Protection disabled, the head's ad-hoc build (CDHash 602acf9a) installed over the previous shell-based agent with the head's install.sh. Full report with the plist and launchctl print captures.

Check Result
Install with SIP disabled Pass. install.sh chose the external shell verifier: the plist runs /bin/sh -c with codesign --verify --strict against the pinned cdhash, with no AssociatedBundleIdentifiers or SpawnConstraint. The agent ran every 60 s with exit 0 and a clean journal, and the menu bar app didn't open.
A second arm() on the same build Pass. The job stayed loaded, its run count kept rising, and the arm still picked the shell verifier.
Recovery after a restart Pass. A 2 minute session, the app killed with kill -9, the VM restarted. Without opening Insomnia, the agent restored sleep 27 s after the deadline: SleepDisabled 0, session.json gone, last exit 0.
An edited sealed backstop.sh Pass. One appended comment line: the agent exited 1 with "does not satisfy the pinned code requirement; backstop.sh not run", and no backstop line followed. A reinstall brought exit 0 back.
Launch cost, 5 warm runs of the agent's command line 0.14, 0.12, 0.12, 0.12 and 0.13 s

Login Items & Extensions, before the upgrade, after it and after the restart, showed the same row each time:

That is the shell verifier as designed: only the native plist carries AssociatedBundleIdentifiers, so the Insomnia name and icon come with SIP enabled. 0f6799e says so in docs/install.md and in the releasing.md check, so a tester with SIP off doesn't read the sh row as a failed upgrade.

Not covered. The native path needs SIP enabled, which a VM here doesn't have: Login Items showing Insomnia, SpawnConstraint enforcement, OS_REASON_CODESIGNING for a replaced binary, and an older binary under the native plist. Those stay with the releasing.md checks on a real Mac.

@krishhgg
krishhgg changed the base branch from integration/wave1-base to main November 8, 2026 01:24
Main moved on with #148, #165, #145, #146 and #147. wave1-base merged earlier copies of #120, #146 and #147, so this branch and main had several merge bases and GitHub reported a conflict. The merge needed no hand edits.
@krishhgg krishhgg added the accepted The owner accepted this pull request; merge-gate/accepted reads it. Only the owner adds it. label Nov 8, 2026
@krishhgg

krishhgg commented Nov 8, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 89a5f33b83

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review · Automatically triggered

Security review completed. No security issues were found in this pull request.

Reviewed commit: 89a5f33b83

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@krishhgg

krishhgg commented Nov 9, 2026

Copy link
Copy Markdown
Owner Author

Real-Mac run at 89a5f33 on the maintainer's MacBook (Mac17,2, macOS 26.2, SIP enabled), installed with that build's cdhash pinned. Everything passed.

Login Items. macOS's own Login Items record (sfltool dumpbtm) is the source here, since System Settings opened on another Space during the first check.

  • Before the install, the recovery agent was listed as sh, from an unidentified developer.
  • After the install, it was listed as Insomnia, from an unidentified developer, with the app's own binary as its executable. System Settings showed it with the app's icon.
  • After a log out and log in, it was still listed as Insomnia, enabled and allowed.
  • No Background Items notification appeared at the install, and the Notification Center database has none.

The launcher's pinning.

  • In the 70 s after the install, the agent ran twice, exited 0 both times, and opened no Insomnia process.
  • Under the spawn constraint, the pinned executable ran and another executable did not. Without the constraint, the other executable ran.
  • With an older bundle in place, launchd refused to spawn it (OS_REASON_CODESIGNING), and no Insomnia process started.
  • With backstop.sh edited inside the bundle, the agent exited 1, logged that the bundle doesn't satisfy the pinned code requirement, and ran nothing. A reinstall put it back.
  • The native launcher takes 0.01 s per run, the same as the shell verifier.

Recovery after a log in. The agent loaded at login ran every minute, 11 runs in the first 11 minutes, all exiting 0. A 5-minute session then disabled sleep and turned on Low Power Mode, and the app was force-quit. 34 s after the session's end time, the agent restored both and cleared the journal:

04:22:19Z backstop: session expired (endsAt=2026-11-09T04:21:46Z); restoring from journal
04:22:19Z backstop: pmset -a disablesleep 0 ok
04:22:19Z backstop: pmset -b lowpowermode 0 ok
04:22:19Z backstop: journal cleared

The app also opened at login. That came from its own Open at Login entry, which was there before the install, not from the agent.

@krishhgg
krishhgg marked this pull request as draft November 9, 2026 04:23
@krishhgg
krishhgg marked this pull request as ready for review November 9, 2026 04:23
@krishhgg
krishhgg merged commit 1044770 into main Nov 9, 2026
22 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accepted The owner accepted this pull request; merge-gate/accepted reads it. Only the owner adds it.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants