-
-
Save kristovatlas/544b2d7a8314cf21c67e33b5a081695a to your computer and use it in GitHub Desktop.
| #!/usr/bin/env bash | |
| # install-claude-verified.sh — download and install Claude Code with full | |
| # signature verification, no unauthenticated bootstrap script. | |
| # | |
| # Usage: ./install-claude-verified.sh [VERSION] | |
| # VERSION defaults to whatever $REPO/latest reports. | |
| # Requires: curl, gpg, jq, sha256sum | |
| # Trust anchor: the pinned fingerprint below (from code.claude.com/docs/en/setup). | |
| # | |
| # Template tip: vendor the key file into your image at $VENDORED_KEY and this | |
| # script will use it instead of fetching the key from the same origin as the | |
| # binaries. | |
| set -euo pipefail | |
| REPO="https://downloads.claude.ai/claude-code-releases" | |
| KEY_URL="https://downloads.claude.ai/keys/claude-code.asc" | |
| PINNED_FPR="31DDDE24DDFAB679F42D7BD2BAA929FF1A7ECACE" | |
| VENDORED_KEY="${VENDORED_KEY:-/opt/provision/claude-code.asc}" | |
| for cmd in curl gpg jq sha256sum; do | |
| command -v "$cmd" >/dev/null || { echo "missing dependency: $cmd" >&2; exit 1; } | |
| done | |
| WORK=$(mktemp -d) | |
| export GNUPGHOME="$WORK/gnupg" # isolated keyring; never touches the user's | |
| mkdir -p -m 700 "$GNUPGHOME" | |
| trap 'rm -rf "$WORK"' EXIT | |
| # --- 1. Obtain the release signing key --------------------------------------- | |
| if [ -f "$VENDORED_KEY" ]; then | |
| cp "$VENDORED_KEY" "$WORK/key.asc" | |
| echo "using vendored key: $VENDORED_KEY" | |
| else | |
| echo "vendored key not found; fetching from $KEY_URL" | |
| curl -fsSL "$KEY_URL" -o "$WORK/key.asc" | |
| fi | |
| # --- 2. Pin the fingerprint BEFORE trusting the key -------------------------- | |
| ACTUAL_FPR=$(gpg --with-colons --import-options show-only --import "$WORK/key.asc" \ | |
| | awk -F: '/^fpr:/ {print $10; exit}') | |
| if [ "$ACTUAL_FPR" != "$PINNED_FPR" ]; then | |
| echo "FATAL: key fingerprint mismatch" >&2 | |
| echo " expected: $PINNED_FPR" >&2 | |
| echo " got: $ACTUAL_FPR" >&2 | |
| exit 1 | |
| fi | |
| gpg --quiet --import "$WORK/key.asc" | |
| # --- 3. Resolve version ------------------------------------------------------- | |
| VERSION="${1:-$(curl -fsSL "$REPO/latest")}" | |
| [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]] || { | |
| echo "FATAL: '$VERSION' is not a valid version string" >&2; exit 1; } | |
| echo "version: $VERSION (manifest signatures exist for >= 2.1.89)" | |
| # --- 4. Fetch and verify the signed manifest ---------------------------------- | |
| curl -fsSL "$REPO/$VERSION/manifest.json" -o "$WORK/manifest.json" | |
| curl -fsSL "$REPO/$VERSION/manifest.json.sig" -o "$WORK/manifest.json.sig" | |
| # Require not just "a good signature" but a good signature FROM THE PINNED KEY. | |
| gpg --status-fd 1 --verify "$WORK/manifest.json.sig" "$WORK/manifest.json" 2>/dev/null \ | |
| | grep -q "VALIDSIG $PINNED_FPR" \ | |
| || { echo "FATAL: manifest signature invalid or from wrong key" >&2; exit 1; } | |
| echo "manifest signature: OK ($PINNED_FPR)" | |
| # --- 5. Detect platform (matches install.sh's logic) -------------------------- | |
| case "$(uname -m)" in | |
| x86_64|amd64) arch="x64" ;; | |
| arm64|aarch64) arch="arm64" ;; | |
| *) echo "unsupported arch: $(uname -m)" >&2; exit 1 ;; | |
| esac | |
| if ldd /bin/ls 2>&1 | grep -q musl; then | |
| platform="linux-$arch-musl" | |
| else | |
| platform="linux-$arch" | |
| fi | |
| # --- 6. Download binary and verify against the signed manifest ---------------- | |
| CHECKSUM=$(jq -re ".platforms[\"$platform\"].checksum" "$WORK/manifest.json") | |
| [[ "$CHECKSUM" =~ ^[a-f0-9]{64}$ ]] || { | |
| echo "FATAL: no checksum for $platform in manifest" >&2; exit 1; } | |
| BIN="$WORK/claude-$VERSION-$platform" | |
| curl -fsSL "$REPO/$VERSION/$platform/claude" -o "$BIN" | |
| ACTUAL=$(sha256sum "$BIN" | cut -d' ' -f1) | |
| if [ "$ACTUAL" != "$CHECKSUM" ]; then | |
| echo "FATAL: binary checksum mismatch" >&2 | |
| echo " manifest: $CHECKSUM" >&2 | |
| echo " actual: $ACTUAL" >&2 | |
| exit 1 | |
| fi | |
| echo "binary checksum: OK ($platform)" | |
| # --- 7. Install ---------------------------------------------------------------- | |
| chmod +x "$BIN" | |
| "$BIN" install "$VERSION" | |
| echo "installed Claude Code $VERSION (verified against signed manifest)" |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| # ── Helpers ────────────────────────────────────────────────────── | |
| info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; } | |
| ok() { printf '\033[1;32m[OK]\033[0m %s\n' "$*"; } | |
| err() { printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2; } | |
| # ── Pre-flight: require npm ────────────────────────────────────── | |
| if ! command -v npm &>/dev/null; then | |
| err "npm is not installed. Please install Node.js/npm first." | |
| exit 1 | |
| fi | |
| info "Node $(node -v) / npm $(npm -v)" | |
| # ── Check for Socket Firewall (sfw) ───────────────────────────── | |
| if command -v sfw &>/dev/null; then | |
| ok "Socket Firewall is already installed: $(sfw --version 2>/dev/null || echo 'version unknown')" | |
| else | |
| info "Socket Firewall not found. Installing globally via npm..." | |
| npm i -g sfw | |
| # Verify the install succeeded | |
| if command -v sfw &>/dev/null; then | |
| ok "Socket Firewall installed successfully." | |
| else | |
| err "sfw command not found after install. Check that npm's global bin directory is in your PATH." | |
| err "Hint: npm config get prefix → add <prefix>/bin to your PATH" | |
| exit 1 | |
| fi | |
| fi | |
| # ── Clear npm cache (recommended by Socket before first use) ───── | |
| info "Clearing npm cache so sfw can intercept all network requests..." | |
| npm cache clean --force | |
| # ── Run the guarded install ────────────────────────────────────── | |
| info "Running: sfw npm i -g @openai/codex" | |
| sfw npm i -g @openai/codex | |
| ok "Done! @openai/codex installed with Socket Firewall protection." |
| curl -fsSL https://code.kimi.com/kimi-code/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')"; if [ "$checksum" = "638927825e96825edbb563de5e0cb06f8a0551c53e026ade8b717b0f25cb83d2" ]; then echo "Checksum matched."; echo "Proceed with installation? (Y/n)"; read response; if [ "$response" = "Y" ] || [ "$response" = "y" ] || [ -z "$response" ]; then bash install.sh && rm -f install.sh; else echo "Installation aborted."; rm -f install.sh; exit 0; fi; else echo "Error: Checksum failed"; exit 1; fi |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| OPENCODE_PKG="opencode-ai" # npm package for SST's opencode CLI — verify this matches what you intend before relying on it | |
| ZAI_PKG="@z_ai/coding-helper" | |
| # ── Helpers ────────────────────────────────────────────────────── | |
| info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; } | |
| ok() { printf '\033[1;32m[OK]\033[0m %s\n' "$*"; } | |
| err() { printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2; } | |
| # ── Pre-flight: require npm ────────────────────────────────────── | |
| if ! command -v npm &>/dev/null; then | |
| err "npm is not installed. Please install Node.js/npm first." | |
| exit 1 | |
| fi | |
| info "Node $(node -v) / npm $(npm -v)" | |
| # ── Check for Socket Firewall (sfw) ───────────────────────────── | |
| if command -v sfw &>/dev/null; then | |
| ok "Socket Firewall is already installed: $(sfw --version 2>/dev/null || echo 'version unknown')" | |
| else | |
| info "Socket Firewall not found. Installing globally via npm..." | |
| npm i -g sfw | |
| if command -v sfw &>/dev/null; then | |
| ok "Socket Firewall installed successfully." | |
| else | |
| err "sfw command not found after install. Check that npm's global bin directory is in your PATH." | |
| err "Hint: npm config get prefix → add <prefix>/bin to your PATH" | |
| exit 1 | |
| fi | |
| fi | |
| # ── Clear npm cache (recommended by Socket before first use) ───── | |
| # npx resolves through the same cache, so a stale cache means sfw | |
| # never sees the fetch. | |
| info "Clearing npm cache so sfw can intercept all network requests..." | |
| npm cache clean --force | |
| # ── Install a package globally under the firewall ──────────────── | |
| install_with_sfw() { | |
| local pkg="$1" | |
| info "Running: sfw npm i -g $pkg" | |
| sfw npm i -g "$pkg" | |
| ok "$pkg installed with Socket Firewall protection." | |
| } | |
| # ── Fetch opencode first, under the firewall ────────────────────── | |
| install_with_sfw "$OPENCODE_PKG" | |
| # ── Fetch zai under the firewall ────────────────────────────────── | |
| install_with_sfw "$ZAI_PKG" | |
| # ── Install shell aliases so future launches stay gated ─────────── | |
| # Without these, typing `npx <pkg>` out of habit runs the TUI with | |
| # unrestricted network access — the firewall only ever covers the | |
| # command it directly wraps. The aliases make the safe form the default. | |
| declare -A ALIASES=( | |
| [opencode]="sfw npx --yes ${OPENCODE_PKG}" | |
| [zai-helper]="sfw npx --yes ${ZAI_PKG}" | |
| ) | |
| # Write to whichever rc files actually exist; fall back to ~/.bashrc. | |
| RC_FILES=() | |
| for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do | |
| [[ -f "$rc" ]] && RC_FILES+=("$rc") | |
| done | |
| [[ ${#RC_FILES[@]} -eq 0 ]] && RC_FILES=("$HOME/.bashrc") | |
| for rc in "${RC_FILES[@]}"; do | |
| for alias_name in "${!ALIASES[@]}"; do | |
| alias_line="alias ${alias_name}='${ALIASES[$alias_name]}'" | |
| # Match on the alias name, not the whole line, so an older version | |
| # of the alias gets reported instead of silently duplicated. | |
| if grep -q "alias ${alias_name}=" "$rc" 2>/dev/null; then | |
| info "An alias named '${alias_name}' already exists in ${rc} — leaving it alone." | |
| else | |
| { | |
| printf '\n# Added by install-opencode-zai-sfw.sh — run the CLI behind Socket Firewall\n' | |
| printf '%s\n' "$alias_line" | |
| } >> "$rc" | |
| ok "Added '${alias_name}' alias to ${rc}" | |
| fi | |
| done | |
| done | |
| # Aliases are read at shell startup, so these are not live yet in the | |
| # caller's session. | |
| info "Run 'source ${RC_FILES[0]}' or open a new shell to use: opencode, zai-helper" | |
| # ── Launch zai, still gated ─────────────────────────────────────── | |
| info "Launching: sfw npx $ZAI_PKG" | |
| exec sfw npx --yes "$ZAI_PKG" "$@" |
| curl -fsSL https://claude.ai/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')" | |
| if [ "$checksum" = "3a68d3406cf674e17bed1733a4dcf37805e2e47d87417700007d7e1aa766a944" ]; then | |
| echo "Checksum matched." | |
| echo "Proceed with installation? (Y/n)" | |
| read response | |
| if [ "$response" = "Y" ] || [ "$response" = "y" ] || [ -z "$response" ]; then bash install.sh && rm -f install.sh; else | |
| echo "Installation aborted." | |
| rm -f install.sh | |
| exit 0 | |
| fi | |
| else | |
| echo "Error: Checksum failed" | |
| exit 1 | |
| fi |
| curl -fsSL https://claude.ai/install.sh -o install.sh && checksum="$(sha256sum install.sh | awk '{print $1}')"; if [ "$checksum" = "3a68d3406cf674e17bed1733a4dcf37805e2e47d87417700007d7e1aa766a944" ]; then echo "Checksum matched."; echo "Proceed with installation? (Y/n)"; read response; if [ "$response" = "Y" ] || [ "$response" = "y" ] || [ -z "$response" ]; then bash install.sh && rm -f install.sh; else echo "Installation aborted."; rm -f install.sh; exit 0; fi; else echo "Error: Checksum failed"; exit 1; fi |
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| OPENCODE_PKG="opencode-ai" # npm package for SST's opencode CLI | |
| # ── Helpers ────────────────────────────────────────────────────── | |
| info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; } | |
| ok() { printf '\033[1;32m[OK]\033[0m %s\n' "$*"; } | |
| err() { printf '\033[1;31m[ERROR]\033[0m %s\n' "$*" >&2; } | |
| # ── Pre-flight: require npm ────────────────────────────────────── | |
| if ! command -v npm &>/dev/null; then | |
| err "npm is not installed. Please install Node.js/npm first." | |
| exit 1 | |
| fi | |
| info "Node $(node -v) / npm $(npm -v)" | |
| # ── Check for Socket Firewall (sfw) ───────────────────────────── | |
| if command -v sfw &>/dev/null; then | |
| ok "Socket Firewall is already installed: $(sfw --version 2>/dev/null || echo 'version unknown')" | |
| else | |
| info "Socket Firewall not found. Installing globally via npm..." | |
| npm i -g sfw | |
| if command -v sfw &>/dev/null; then | |
| ok "Socket Firewall installed successfully." | |
| else | |
| err "sfw command not found after install. Check that npm's global bin directory is in your PATH." | |
| err "Hint: npm config get prefix → add <prefix>/bin to your PATH" | |
| exit 1 | |
| fi | |
| fi | |
| # ── Clear npm cache (recommended by Socket before first use) ───── | |
| # npm resolves through the same cache, so a stale cache means sfw | |
| # never sees the fetch. | |
| info "Clearing npm cache so sfw can intercept all network requests..." | |
| npm cache clean --force | |
| # ── Install opencode globally, under the firewall ───────────────── | |
| # Note: sfw gates package-manager traffic (installs, updates). It does | |
| # not sandbox the runtime network activity of the installed app, so a | |
| # global install gated here is just as protected as launching via | |
| # `sfw npx` every time — and starts faster. | |
| info "Running: sfw npm i -g $OPENCODE_PKG" | |
| sfw npm i -g "$OPENCODE_PKG" | |
| ok "$OPENCODE_PKG installed with Socket Firewall protection." | |
| if ! command -v opencode &>/dev/null; then | |
| err "opencode command not found after install. Check your PATH (npm config get prefix → <prefix>/bin)." | |
| exit 1 | |
| fi | |
| # ── Gate future updates too ─────────────────────────────────────── | |
| # Updating is the moment new package code enters your machine, so it | |
| # should go through sfw just like the install did. | |
| UPDATE_ALIAS="alias opencode-update='sfw npm update -g ${OPENCODE_PKG}'" | |
| RC_FILES=() | |
| for rc in "$HOME/.bashrc" "$HOME/.zshrc"; do | |
| [[ -f "$rc" ]] && RC_FILES+=("$rc") | |
| done | |
| [[ ${#RC_FILES[@]} -eq 0 ]] && RC_FILES=("$HOME/.bashrc") | |
| for rc in "${RC_FILES[@]}"; do | |
| if grep -q "alias opencode-update=" "$rc" 2>/dev/null; then | |
| info "An 'opencode-update' alias already exists in ${rc} — leaving it alone." | |
| else | |
| { | |
| printf '\n# Added by install-opencode-sfw.sh — update opencode behind Socket Firewall\n' | |
| printf '%s\n' "$UPDATE_ALIAS" | |
| } >> "$rc" | |
| ok "Added 'opencode-update' alias to ${rc}" | |
| fi | |
| done | |
| printf '\n' | |
| ok "opencode is installed." | |
| printf '\n' | |
| info "NEXT STEP — connect a model provider (both are built into opencode):" | |
| info " opencode auth login" | |
| info " • pick 'Z.AI Coding Plan' to use your GLM Coding Plan subscription" | |
| info " • run it again and pick 'OpenRouter' to add your OpenRouter API key" | |
| info " Both can be connected at once; switch models anytime with /models in the TUI." | |
| printf '\n' | |
| info "Other commands:" | |
| info " opencode launch the TUI" | |
| info " opencode-update update opencode behind Socket Firewall (open a new shell first)" |
Latest CC review:
Review the change to this script for malicious intent:
Nothing in this fragment looks malicious. Walking through the parts that would matter:
The two curl lines are inert. Both sit inside echo string arguments going to stderr — they're guidance text, never executed. The URL is https://claude.ai/install.sh: correct domain spelling, no typosquat, no lookalike TLD, HTTPS. The # pinned-dep-allow comments accurately describe what they're suppressing, which is a good sign rather than a red flag. One thing to confirm in review: that the lint rule those comments suppress is line-scoped, so a suppression can't accidentally cover a genuinely executed fetch elsewhere in the file.
The guard's logic is sound and its direction is privilege-reducing. It fires only when euid is 0 and SUDO_USER is set to a non-root user, so plain root (containers, CI, root-only boxes) is untouched, as the comment claims. ${SUDO_USER:-} and ${CLAUDE_INSTALL_ALLOW_SUDO:-} are properly defaulted for set -u. Nothing here writes files, reads credentials, or touches the network. A change that refuses root is the opposite shape from what an attacker inserts.
Three things worth flagging as ordinary review comments:
- The suggested override command probably doesn't work on default sudoers.
sudo CLAUDE_INSTALL_ALLOW_SUDO=1 bashsets the variable via sudo, which most default configs reject ("you are not allowed to set the following environment variables") unless the sudoers rule carriesSETENVor the name is inenv_keep.sudo env CLAUDE_INSTALL_ALLOW_SUDO=1 bashis the portable form. Users hitting a hardexit 1and then a second failure on the documented escape hatch is a bad path. - The detection has a known hole.
sudo -iorsudo su -resets the environment, droppingSUDO_USER, so a user who takes a root login shell first sails past the guard and installs into/root— exactly the footgun being defended against. Probably acceptable, but it means the check catches the common form, not the class. - It's a breaking change for anyone whose automation currently does
curl … | sudo bash. Those pipelines will start failing at this newexit 1. Worth a changelog note.
The snippet is cut off at both ends, so I can't see the check that precedes it or confirm the exit 1 that presumably follows these messages. If you want a verdict on the whole change, paste the full diff — in particular anything downstream that resolves $HOME or does the actual download and chmod, since that's where an installer's real risk lives.
Full script confirms it: no malicious intent, and the change is defensive rather than the reverse. Summary of the review, plus a correction to something I said earlier.
The sudo guard. Placement is good — it sits after argument validation and before any network activity or filesystem writes, so it fails early and cheaply. The logic matches the comment: it fires only on euid 0 with a non-root SUDO_USER, leaving plain root untouched. Nothing in the block touches the network, credentials, or disk. One correction to my earlier note: I said the ${SUDO_USER:-} defaults were "properly defaulted for set -u" — the script only sets set -e, so those defaults aren't load-bearing. Harmless either way, but I overstated it. The exit 1 I couldn't see is present and correct.
The rest of the script checks out. Both curl invocations in the error text remain inert (echo to stderr). The real fetches go to downloads.claude.ai over HTTPS, no IP literals or lookalike hosts. The trust chain is sound: binary verified against a SHA256 from manifest.json on the same origin, checksum format anchored to ^[a-f0-9]{64}$, mismatch deletes the file and exits nonzero, chmod +x happens only after verification, and the download is removed afterward. No eval, no base64 blobs, no shell-rc writes, no persistence, no env exfiltration. TARGET reaches the binary as a single quoted argv element and its regex forbids a leading -, so no option or shell injection.
Three defense-in-depth notes, none of them about the change itself:
- The version regex is anchored only at the front (
^[0-9]+\.[0-9]+\.[0-9]+), unlike the fully anchoredTARGETcheck.$versionthen flows intobinary_path="$DOWNLOAD_DIR/claude-$version-$platform", so server-controlled content like1.2.3/../../../../tmp/xwould place and execute the file outside$DOWNLOAD_DIR. It only matters ifdownloads.claude.aiitself is serving bad content — in which case you have worse problems — but adding(-[^[:space:]]+)?$costs nothing. - No
set -o pipefail. It happens to be safe here: every pipeline that could swallow a failure (shasum | cut,jq) yields an empty string that then fails a subsequent check. That's fail-safe by accident rather than by construction. - The jq-less manifest parser is brittle but not exploitable.
[^}]*can't cross the closing brace of the platform's object, so it can't bind a different platform's checksum, and$platforminterpolates from a fixed set ofuname-derived literals. It does silently depend onchecksumappearing after the platform key.
My two substantive comments on the change stand: sudo VAR=1 bash is rejected by default sudoers without SETENV, so the documented escape hatch will likely fail for the people who need it (sudo env CLAUDE_INSTALL_ALLOW_SUDO=1 bash is portable), and sudo -i/sudo su - drops SUDO_USER and walks straight past the guard into /root.
updated zai script to install opencod first since zai has no TUI
Fable 5 review of latest claude code install.sh:
Verdict: clean. I diffed it against the live official installer — https://claude.ai/install.sh currently redirects to downloads.claude.ai/claude-code-releases/bootstrap.sh, and your uploaded file matches that content line for line, including the comments and the internal pinned-dep-allow lint annotations. This is Anthropic's own bootstrap installer, not a modified copy.
What I checked and why it passes:
Network behavior. The only endpoints contacted are https://downloads.claude.ai/claude-code-releases/... (version file, manifests, binary). Nothing is sent outbound beyond the GET requests themselves — no telemetry, no exfiltration of env vars or files, no eval, no base64/obfuscated payloads, no writes outside $HOME/.claude (plus whatever claude install itself does).
Input handling. The one user input, $TARGET, is validated against a strict regex (stable|latest|semver) before ever being used, and it's quoted when passed to the binary. No injection surface.
Integrity checks — including the two spots that look sketchy but aren't. Both download paths (zstd-compressed and plain) require a SHA-256 match against the manifest before the binary runs.
The zstd -d ... | head -c "$size" > "$binary_path" || true line looks like a suppressed failure, but it fails open into the fallback path, not into execution: if the decompressed output doesn't match the manifest checksum, verified stays false and the script re-downloads the plain binary with a hard checksum check that exits on mismatch. A tampered file can never reach chmod +x + execution.
The head -c "$size" truncation is similarly bounded by the checksum verification right after it, so it can't be used to smuggle or trim content undetected.
Execution. Yes, it downloads and runs an arbitrary binary ("$binary_path" install) — that's the entire purpose of a bootstrap installer, and it's gated behind the checksum. The sudo guard, Rosetta/musl detection, stty sane recovery, and OOM-137 messaging are all benign housekeeping.
One real limitation worth knowing, though it's a design property of the official installer rather than something surreptitious in this copy: the checksums come from the same server as the binaries, so the verification protects against corruption, truncation, and CDN-level tampering of a single file — not against a fully compromised origin or a TLS MITM with a trusted cert. There's no independent signature (GPG/sigstore) verification. If your threat model includes a compromised downloads.claude.ai, no amount of reading this script helps; short of that, it's safe to run.
Today I'm adding the Kimi Code CLI install.sh.
Reviews: Opus 4.8 Max for malicious intent / modification:
virustotal.com: 0/61, but "Matches rule Usage Of Web Request Commands And Cmdlets" and "Matches rule Curl Usage on Linux by Nasreddine Bencherchali (Nextron Systems) at Sigma Integrated Rule Set (GitHub)"
638927825e96825edbb563de5e0cb06f8a0551c53e026ade8b717b0f25cb83d2