Skip to content

Install sys1rust from GitHub Releases and remove Homebrew - #38

Merged
krishhgg merged 8 commits into
mainfrom
install/1-script
Oct 7, 2026
Merged

krishhgg merged 8 commits into
mainfrom
install/1-script

Conversation

@krishhgg

@krishhgg krishhgg commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

The README currently sends users through a Homebrew tap. Install directly from this repository's GitHub Releases instead, with a root install.sh that chooses the macOS bundle, checks SHA256SUMS and links the binary under ~/.local without sudo. --service starts it at login through launchd; --uninstall keeps the downloaded models.

Record the installer's owned paths, reject unrelated prefix contents and bin links, keep replacement directories immutable, and serialize install, update and uninstall with locks on the prefix, bin directory and shared LaunchAgent path. Validate the release before creating bin directories, so missing releases and checksum failures can be retried with nested bin paths. Updates switch current atomically and keep the previous install. Service updates persist a pending restart before switching current and recover it on retry. Readiness requires the LaunchAgent PID to own the listening socket and answer /health. Updates read their saved port and cache from the plist; relative cache paths become absolute and printed commands quote shell metacharacters.

Remove the Homebrew formula and tap publishing step. CI installs and uninstalls through the same script, and the README documents that route. The agent prompt and skills follow in the next PR. The release checklist checks the candidate's own PID and free port with a deadline and stops at the first failed command.

Validation:

  • 117 installer fixture checks pass under /bin/sh and /bin/dash, including interrupted and failed restarts, foreground listeners, overlapping installs across prefixes and shared paths, failed first installs with nested bin paths, foreign files, service settings and command quoting.
  • shellcheck, actionlint and shell syntax checks pass.
  • A real LaunchAgent install, interrupted update recovery, ordinary update, rerun and uninstall passed on a nondefault port; cleanup removed the service and install and kept the models.
  • The documented candidate check passed; the installed bundle passed 24 smoke requests and 120 questions with zero failures.
  • Against GitHub, the installer reports that no release is published and leaves no prefix. Real release asset downloads and the public curl | sh path still need the release candidate.

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the failed-download retry issue is fixed and no new blocking issue was found.

What we checked:

  • Failed downloads allow retries: get_bundle runs before the bin directory is created. Cleanup can therefore remove the empty prefix after a missing release or bad checksum.
  • Bin conflicts stop link changes: After taking the bin lock, the installer checks ownership again. A foreign link stops the install before the bundle moves or either link changes.

Summary

This PR replaces Homebrew installation with install.sh, which downloads and checks GitHub Release bundles, manages owned files, and optionally starts a LaunchAgent.

  • The latest change fixes retries after failed downloads with a nested bin directory.
  • Bin ownership is still checked under a lock before either link changes.
  • CI and the release checklist use the installer. No new actionable issues were found.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Lock prefix and shared service path] --> B[Check existing links]
  B --> C[Download and check bundle]
  C --> D[Create registry]
  D --> E[Lock bin directory]
  E --> F[Recheck bin ownership]
  F --> G[Move bundle and switch current]
  G --> H[Restart owned service if needed]
  C -->|Failure| I[Remove staging directory and empty prefix]
Loading

Reviews (3) · Last reviewed commit: "Defer bin directories until the release ..."

krishhgg and others added 5 commits October 6, 2026 13:30
install.sh checks for an Apple silicon Mac on macOS 14.0 or later outside
Rosetta, and picks the macos26 bundle on macOS 26.2 or later, else macos14.
It resolves the latest final release through the releases/latest redirect,
or takes --version, downloads the bundle with curl, and checks it against
the release's SHA256SUMS before unpacking. --from DIR installs a local
dist dir instead.

Each version unpacks into PREFIX/<version>-<flavor>. A rename swaps the
current link, the previous link keeps the last version, and older
versions are removed. BIN_DIR/sys1rust links to PREFIX/current. It runs
without sudo, never edits rc files and never downloads models. curl sets
no quarantine flag, so the script leaves xattrs alone.

--service writes and loads a LaunchAgent that runs sys1rust serve, passes
HF_HUB_CACHE, HF_HOME, XDG_CACHE_HOME and LAYA_PORT through, and waits for
/health. An update restarts a running service with launchctl kickstart -k.
--uninstall stops the service, removes the install, its link and the log,
and prints the model cache path, its size and the command to delete it.

packaging/test_install.sh runs install.sh under a given shell against
fake bundles, a local release server and a fake launchctl. It needs no
network, GPU or launchd.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The smoke jobs install each bundle with install.sh --from dist into the
runner's temp dir, check that it picked the bundle for the runner's
macOS, run version, models, pull and the smoke test through the link,
then run install.sh --uninstall and check that the prefix and the link
are gone.

The build job now runs packaging/test_install.sh under sh and dash, and
writes SHA256SUMS next to the bundles, so the smoke jobs check the same
hashes the release publishes. The publish job checks the bundles against
it and needs no checkout.

The Homebrew tap step, the TAP_TOKEN check, the tap-update concurrency
group, packaging/render_formula.sh and packaging/sys1rust.rb.in are gone.
The draft and rerun guards of the GitHub release step stay as they were.
A pull request that changes install.sh now runs the workflow too.

download.rs: a doc comment named the brew services log as the place
where progress prints a line at every 10%. It now names the log of the
install.sh --service LaunchAgent.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Step 5 installs the candidate with install.sh --version into a scratch
prefix, checks /health from sys1rust serve in the shell and then from
the --service LaunchAgent, which reuses this shell's HF_HUB_CACHE, and
uninstalls it. Step 7 checks the one-line curl | sh install from main,
the service and the uninstall on a clean account.

The tap steps, the TAP_TOKEN note and the note on the tap-update group
are gone. The rerun and draft guidance stays under "If the publish job
fails". The intro names packaging/test_install.sh.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Record the directories and links install.sh creates, refuse unrelated prefix contents, and remove only registered paths. Install every replacement into an immutable directory, switch current in one rename, and serialize mutations with a prefix lock. Keep both possible link targets registered across interruptions.

Read service settings from its plist on update and uninstall, make relative cache paths absolute, preserve replaced logs, and quote generated shell commands. Replace the README Homebrew instructions so this PR has a working install guide by itself.

The installer passes 96 checks under sh and dash, shellcheck and actionlint. The real LaunchAgent install, update, rerun and uninstall cycle passed on a nondefault port. The installed release bundle passed 120 smoke questions with no failures.

Co-Authored-By: Codex <noreply@openai.com>
Run the candidate on a free port, check its own readiness line and process id, and stop it even when a check fails. Add a startup deadline and preserve the first failed command's status in the build and candidate steps.

The documented candidate check ran against the installed bundle. Controlled build and install failures stopped the checklist with their original exit codes.

Co-Authored-By: Codex <noreply@openai.com>
The macOS runner reached the port-file read before the Python fixture server became ready. Replace the 5 s assumptions with bounded 60 s waits, check each child is alive, and print the release-server log when startup fails.

All 96 checks pass with a deliberately delayed 6 s server startup under sh, and all 96 pass under dash. Shellcheck passes.

Co-Authored-By: Codex <noreply@openai.com>
Comment thread install.sh Outdated
Comment thread install.sh Outdated
Comment thread install.sh
Record a pending service restart before switching current, and keep it until the LaunchAgent owns its listening socket and answers /health. A retry now restarts an old process even when an interrupted update already switched the version link. Failed restarts remain recoverable.

Lock the bin directory and shared LaunchAgent path alongside the prefix before checking or modifying them. This prevents installs with different prefixes, bin directories or HOME values from racing shared paths.

Add regression cases for interrupted and failed restarts, healthy foreground listeners, and overlapping installs. All 113 fixture checks pass under sh and dash. ShellCheck, shell syntax checks and actionlint pass. A real LaunchAgent update recovers from a signal after the current switch, runs the new executable, retains its saved cache and port, and uninstalls cleanly.

Co-Authored-By: Codex <noreply@openai.com>
Comment thread install.sh Outdated
Create the bin directory only after validating the bundle and registering the prefix. Missing releases and checksum failures now leave no nested bin parents, so a retry accepts the same prefix without manual cleanup.

Keep the bin lock around every version switch, link change and uninstall. Check bin ownership before downloading and again under that lock to preserve protection across callers with different HOME values.

Add missing-release and bad-checksum regression cases with tools/bin inside the prefix, including a successful retry. They fail against the previous installer. All 117 checks pass under sh and dash, and ShellCheck, shell syntax, actionlint and git diff --check pass.

Co-Authored-By: Codex <noreply@openai.com>
@krishhgg
krishhgg merged commit 41daf50 into main Oct 7, 2026
5 checks passed
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