diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..43ad5c7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +# EditorConfig — https://editorconfig.org. Encodes RigForge's house style so editors match CI +# (shfmt -i 4, yamllint, markdownlint) without per-editor setup. +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +# Shell is the core of the repo: 4-space indent, matching `shfmt -i 4` (see the Makefile lint target). +[*.sh] +indent_size = 4 + +# Make needs real tabs in recipes. +[Makefile] +indent_style = tab + +# YAML and JSON conventionally use 2-space indent. +[*.{yml,yaml,json,json.template}] +indent_size = 2 + +# In Markdown, two trailing spaces is a hard line break — don't strip it. +[*.md] +trim_trailing_whitespace = false diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 8ba6044..cc430eb 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -27,14 +27,14 @@ A clear description of the bug — what you expected and what actually happened. Relevant output from the setup script and/or the miner. On Linux: -``` +```bash sudo journalctl -u xmrig --no-pager | tail -n 50 ```
Logs -``` +```text paste logs here ``` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d447ede..f5332e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,33 @@ permissions: contents: read jobs: + lint-yaml: + name: Lint (yamllint) + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false # zizmor: artipacked + # pipx is preinstalled on ubuntu-24.04 (same path as diff-cover/zizmor); pin the version so the + # ruleset can't drift with the runner image. + - name: Install pinned yamllint + run: pipx install "yamllint==1.38.0" + # Via `make lint-yaml` so the file set + .yamllint config live in one place and can't drift from local. + - name: Run yamllint (make lint-yaml) + run: make lint-yaml + + lint-md: + name: Lint (markdownlint) + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false # zizmor: artipacked + # node is preinstalled on ubuntu-24.04; `make lint-md` runs the version-pinned markdownlint-cli2 + # via npx, reading .markdownlint-cli2.yaml — same invocation as local. + - name: Run markdownlint (make lint-md) + run: make lint-md + lint: name: Lint (shellcheck + shfmt) runs-on: ubuntu-24.04 diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml new file mode 100644 index 0000000..ff4c039 --- /dev/null +++ b/.github/workflows/links.yml @@ -0,0 +1,41 @@ +name: Links + +# Link-checking the docs is kept OFF the PR path on purpose: external links are flaky-by-nature +# (rate limits, transient downtime) and shouldn't block unrelated PRs (#118). Instead it runs on a +# weekly schedule against the default branch, plus on demand via the Actions tab. Run it locally any +# time with `make lint-links`. +on: + schedule: + - cron: "0 6 * * 1" # Mondays 06:00 UTC + workflow_dispatch: + +permissions: + contents: read + +jobs: + lychee: + name: Link check (lychee) + runs-on: ubuntu-24.04 + env: + # Pinned + checksum-verified, like the gitleaks/shellcheck installs. Keep in lockstep with the + # version `make lint-links` expects locally. + LYCHEE_VERSION: "0.24.2" + LYCHEE_SHA256: "1f4e0ef7f6554a6ed33dd7ac144fb2e1bbed98598e7af973042fc5cd43951c9a" + # lychee uses GITHUB_TOKEN to make authenticated GitHub requests and dodge the anon rate limit. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false # zizmor: artipacked + - name: Install pinned lychee + run: | + set -euo pipefail + tarball="lychee-x86_64-unknown-linux-gnu.tar.gz" + curl -fsSL "https://github.com/lycheeverse/lychee/releases/download/lychee-v${LYCHEE_VERSION}/${tarball}" -o "$tarball" + echo "${LYCHEE_SHA256} ${tarball}" | sha256sum -c - + tar -xzf "$tarball" + sudo install "lychee-x86_64-unknown-linux-gnu/lychee" /usr/local/bin/lychee + lychee --version + # Via `make lint-links` so the file set + .lychee.toml config are the same locally and in CI. + - name: Link-check docs (make lint-links) + run: make lint-links diff --git a/.lychee.toml b/.lychee.toml new file mode 100644 index 0000000..2ba152a --- /dev/null +++ b/.lychee.toml @@ -0,0 +1,12 @@ +# lychee link-checker config for RigForge docs. Run locally via `make lint-links`; in CI it runs on +# a weekly schedule (external links are flaky-by-nature, so link-checking doesn't gate PRs). +max_retries = 3 +retry_wait_time = 2 +timeout = 20 + +# GitHub is the main rate-limiter; CI passes a GITHUB_TOKEN so authenticated requests dodge the +# anonymous limit. Still accept 429 so a transient rate-limit on some other host can't fail the run. +accept = ["200..=299", "429"] + +# Some hosts reject non-browser user agents; present a common one. +user_agent = "Mozilla/5.0 (compatible; lychee/0.24; +https://github.com/lycheeverse/lychee)" diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml new file mode 100644 index 0000000..ae1ebdf --- /dev/null +++ b/.markdownlint-cli2.yaml @@ -0,0 +1,30 @@ +# markdownlint-cli2 config for RigForge docs. Run via `make lint-md`. +# Structural rules (blank lines around headings/lists/fences, code-fence languages, heading levels) +# are kept and the docs fixed to satisfy them; purely stylistic rules that fight the repo's +# deliberate house style are turned off below. +config: + default: true + # Long, deliberate prose/command lines — length is a review concern, not a linter one. + MD013: false + # Inline HTML is used on purpose:
in issue templates, /badges in the README. + MD033: false + # Bold lead-ins like **HugePages** are inline labels, not headings. + MD036: false + # Templates and partials legitimately don't open with a top-level H1. + MD041: false + # Adjacent-but-separate blockquote callouts are intentional; don't force them to merge. + MD028: false + # Table pipe-spacing is cosmetic; the existing tables are readable and consistent as written. + MD060: false + # Keep-a-Changelog repeats "### Added"/"### Fixed" across version sections — allow non-sibling dups. + MD024: + siblings_only: true + # The repo uses *asterisk* emphasis and **asterisk** strong consistently. + MD049: + style: asterisk + MD050: + style: asterisk +globs: + - "**/*.md" +ignores: + - "node_modules" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 88b3453..bf08da7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,12 +3,33 @@ # pipx install pre-commit # or: pip install pre-commit # pre-commit install # -# Scope here is the secret-scanning gate from #117: gitleaks, pinned to the SAME version CI runs -# (.github/workflows/security.yml) so local catches a leak before it's ever pushed. The broader -# hook set — shellcheck, shfmt, yamllint, markdownlint, and the freebies — is tracked in #118 and -# will be added to this file, keeping the Makefile's SHELL_FILES the source of truth. +# Local == CI: the shell hook calls `make lint`, so the Makefile's SHELL_FILES stays the single +# source of truth (no duplicated file list here). gitleaks is pinned to the same version CI runs +# (.github/workflows/security.yml). The config/docs linters (yamllint, markdownlint, lychee) aren't +# commit-time hooks — run them with `make lint-yaml` / `make lint-md` / `make lint-links`; they gate +# in CI. repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.30.1 # keep in lockstep with GITLEAKS_VERSION in .github/workflows/security.yml hooks: - id: gitleaks + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: detect-private-key + - id: check-added-large-files + - id: end-of-file-fixer + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] # two trailing spaces is a hard line break in Markdown + + - repo: local + hooks: + # Reuse `make lint` rather than re-listing files, so shellcheck/shfmt run over the exact same + # SHELL_FILES set as CI and `make lint`. Requires shellcheck + shfmt on PATH (see CONTRIBUTING). + - id: make-lint + name: shellcheck + shfmt (make lint) + entry: make lint + language: system + files: \.sh$ + pass_filenames: false diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..b37a77d --- /dev/null +++ b/.yamllint @@ -0,0 +1,18 @@ +--- +# yamllint config for RigForge, tuned to the repo's house style rather than yamllint's strict +# defaults: workflows carry long, deliberate explanatory comments, and inline comments use a single +# leading space (the same `key: value # note` style as the shell code). Run via `make lint-yaml`. +extends: default + +rules: + # The workflows intentionally wrap explanation into long inline comments; enforcing 80 cols here + # would mean butchering them. Length is already governed by review, not a linter. + line-length: disable + # Single-document files — the leading `---` adds nothing, so don't require it. + document-start: disable + comments: + # Match the repo style of one space before an inline comment (yamllint defaults to two). + min-spaces-from-content: 1 + truthy: + # Don't flag GitHub Actions' `on:` key as a "truthy" value. + check-keys: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 7687641..f87d036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to RigForge are documented here. The format is based on ## [Unreleased] ### Added + - **Supply-chain & secret-scanning CI gates (#117).** Three cross-cutting hardening gates on top of the existing SHA-pinned actions and commit-verified XMRig build: - **gitleaks** — a new `Security` workflow scans the full git history for committed secrets (pool @@ -22,10 +23,22 @@ All notable changes to RigForge are documented here. The format is based on Advisory Database. Runs on push/PR plus a weekly schedule, so a CVE disclosed against a pinned action trips the gate even with no open PRs. Hardened the existing `ci.yml`/`release.yml` to a read-only default token and `persist-credentials: false` on checkout to make the audit clean. +- **DX glue + config/docs lint (#118).** Rounds out the non-shell tooling around the existing + shellcheck/shfmt + kcov core: + - **`.editorconfig`** — encodes the whitespace house style (`shfmt -i 4`, LF, final newline) so + editors match CI without per-editor setup. + - **pre-commit** — `.pre-commit-config.yaml` now orchestrates `make lint` (shellcheck/shfmt via the + Makefile's `SHELL_FILES`, no duplicated list), the existing gitleaks hook, and freebie hygiene + hooks (private-key detection, large-file guard, end-of-file + trailing-whitespace fixers). + - **yamllint + markdownlint** — new CI gates (and `make lint-yaml` / `make lint-md`) over the + workflows/configs and the docs, each with a tuned config (`.yamllint`, `.markdownlint-cli2.yaml`). + - **lychee** — a link-checker (`make lint-links`) that runs on a weekly schedule rather than per-PR, + since external links are flaky-by-nature. ## [1.0.1] - 2026-06-13 ### Fixed + - **HugePage sizing is now NUMA-aware (1 GB pages) (#111).** RandomX fast mode keeps a NUMA-local copy of the ~2080 MB dataset **per NUMA node**, but the reservation math multiplied the per-dataset 1 GB pages by the **socket** count, not the NUMA-node count. On a single-socket, multi-NUMA CPU — e.g. an EPYC 7642 with 4 @@ -99,6 +112,7 @@ The full walkthrough — prerequisites, the Linux reboot, and verification — i Full 1.0.0 feature list — every capability and hardening that went into this release #### Added + - **Privacy & security, documented up front (#109).** A new README "Privacy & security" section and a SECURITY.md "What RigForge exposes (and what it doesn't)" section state it plainly: **no telemetry** (the only outbound traffic is your pool, the commit-verified XMRig clone, and your distro's package mirrors); @@ -324,6 +338,7 @@ The full walkthrough — prerequisites, the Linux reboot, and verification — i Release with `.zip`/`.tar.gz` deploy bundles, `SHA256SUMS`, and changelog-derived notes (#3, #36). #### Changed + - **Live auto-tuning converges in one run.** Each `autotune` run **live-sweeps every prefetch mode** against the running miner and adopts the fastest (median measurement + a margin gate, else it keeps the current mode), converging in a single ~minutes-long pass. The safety-net timer fires **monthly** by @@ -389,6 +404,7 @@ The full walkthrough — prerequisites, the Linux reboot, and verification — i fixes across the docs. #### Fixed + - **`setup` re-run now applies your `config.json` edits (#109).** On a no-rebuild re-run, the regenerated config was written to the worker root instead of the build directory the service loads (`--config=$BUILD_DIR/config.json`), so an edit-then-`setup` silently kept mining the old config. setup diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 38cfb8a..ac33f68 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,17 +31,34 @@ RigForge is portable Bash that has to run on Ubuntu/Debian and macOS, so: `shfmt` formatting.) - Update the README or other docs when you change behaviour or add options. -## Secret scanning +## Pre-commit hooks -CI runs [gitleaks](https://github.com/gitleaks/gitleaks) over the full history on every push and PR, -so an accidentally committed token or pool credential blocks the merge. Catch it locally first by -installing the pre-commit hook (it runs the same pinned gitleaks on staged changes): +Install the hooks once and they run on every commit, catching issues before they reach CI: ```bash pipx install pre-commit # or: pip install pre-commit pre-commit install ``` +This runs `make lint` (ShellCheck + shfmt over the Makefile's `SHELL_FILES`), +[gitleaks](https://github.com/gitleaks/gitleaks) secret scanning (the same pinned version CI runs, so +a committed token or pool credential is caught before it's pushed), and a few hygiene checks +(private-key detection, a large-file guard, final-newline and trailing-whitespace fixers). + +### Config & docs linting + +The YAML, Markdown, and link checks gate in CI and have matching Make targets for local runs: + +```bash +make lint-yaml # yamllint the workflows + configs (.yamllint) +make lint-md # markdownlint the docs (.markdownlint-cli2.yaml; needs node) +make lint-links # lychee link-check the docs (.lychee.toml; needs lychee — runs weekly in CI) +make lint-all # shell + yaml + markdown in one go +``` + +An [`.editorconfig`](./.editorconfig) encodes the whitespace conventions (`shfmt -i 4`, LF, final +newline) so most editors match these checks automatically. + ## Branching RigForge uses a two-branch model (same as [Pithead](https://github.com/p2pool-starter-stack/pithead)): diff --git a/Makefile b/Makefile index 164a8eb..0ef0321 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,13 @@ # Local test entry points (mirror the GitHub Actions CI jobs). -.PHONY: help test test-suite test-e2e test-e2e-macos smoke coverage e2e-real lint fmt +.PHONY: help test test-suite test-e2e test-e2e-macos smoke coverage e2e-real lint fmt lint-yaml lint-md lint-links lint-all SHELL_FILES = rigforge.sh util/proposed-grub.sh tests/run.sh tests/e2e/linux.sh tests/e2e/in-container.sh tests/e2e/macos.sh tests/smoke.sh tests/coverage.sh tests/e2e-real.sh +# Config/docs lint file sets, derived from what's tracked so CI and local stay in sync (like SHELL_FILES). +YAML_FILES = $(shell git ls-files '*.yml' '*.yaml') +MD_FILES = $(shell git ls-files '*.md') +MARKDOWNLINT_VERSION = 0.22.1 + # Keep `make` (no target) running the default dev check; `make help` lists every target. .DEFAULT_GOAL := test @@ -35,3 +40,14 @@ lint: ## shellcheck + shfmt (check) the script, utilities, and test scripts fmt: ## auto-format all shell scripts with shfmt (resolves shfmt lint failures) shfmt -i 4 -w $(SHELL_FILES) + +lint-yaml: ## yamllint the YAML (workflows, dependabot, configs) — uses .yamllint, strict + yamllint --strict $(YAML_FILES) + +lint-md: ## markdownlint the docs — uses .markdownlint-cli2.yaml (needs node/npx) + npx --yes markdownlint-cli2@$(MARKDOWNLINT_VERSION) $(MD_FILES) + +lint-links: ## lychee link-check the docs — uses .lychee.toml (needs lychee; hits external links) + lychee $(MD_FILES) + +lint-all: lint lint-yaml lint-md ## run every fast linter (shell + yaml + markdown; not the link check) diff --git a/README.md b/README.md index c018fbb..0abd6d6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # RigForge -### Provision a hardware-tuned XMRig miner in one command. +

Provision a hardware-tuned XMRig miner in one command

[![CI](https://github.com/p2pool-starter-stack/rigforge/actions/workflows/ci.yml/badge.svg)](https://github.com/p2pool-starter-stack/rigforge/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE) @@ -198,7 +198,9 @@ For how RigForge is versioned and released, see [RELEASING.md](./RELEASING.md) a If RigForge saved you time and you'd like to support it, donations to this XMR wallet are appreciated: - 486aGn4qhH1MkaASjnEWMDN7stD1SVtPF5fvihmjffeBE5ACL1u1jU95KxiqmoiaPZMexi4R4W11MLXut66XWVVF8wjAE5R +```text +486aGn4qhH1MkaASjnEWMDN7stD1SVtPF5fvihmjffeBE5ACL1u1jU95KxiqmoiaPZMexi4R4W11MLXut66XWVVF8wjAE5R +``` --- diff --git a/RELEASING.md b/RELEASING.md index f47e374..ee00002 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -23,12 +23,14 @@ promoted to **`main`** and tagged. The steps below build the release commit on ` dependency-free suite, the Docker `/etc` e2e, the coverage gate) — but it can't compile XMRig, reserve HugePages, write MSRs, set the governor, or actually hash. So on a **real Linux rig**, run the genuine deploy end to end and assert each step: + ```bash sudo bash tests/e2e-real.sh provision # real deps + XMRig build + tuning + kernel tuning + service sudo reboot # HugePages (1G + GRUB cmdline) take effect on boot; reconnect sudo bash tests/e2e-real.sh verify # doctor (HugePages/MSR/governor/service) + bench (real H/s) + a short tune + a live auto-tune pass sudo bash tests/e2e-real.sh teardown # uninstall + assert a clean revert ``` + Each phase must report `E2E-REAL (): PASS`. This is what proves a release bundle actually builds, tunes, and hashes on real hardware — the suites all stub XMRig and can't. - **Put a real, reachable pool in `config.json` first.** Without one, `setup` writes an unroutable @@ -44,15 +46,20 @@ promoted to **`main`** and tagged. The steps below build the release commit on ` `## [X.Y.Z] - YYYY-MM-DD` heading, then leave a fresh empty `## [Unreleased]` above it. 4. Bump [`VERSION`](./VERSION) to `X.Y.Z`. 5. Commit the two together on `develop`: + ```bash git commit -am "release: vX.Y.Z" git push origin develop ``` + 6. Promote `develop` to `main`: + ```bash git checkout main && git merge --ff-only develop && git push origin main ``` + 7. Tag and push from `main` (annotated tag, **matching `VERSION`**): + ```bash git tag -a vX.Y.Z -m "RigForge vX.Y.Z" git push origin main --follow-tags diff --git a/docs/configuration.md b/docs/configuration.md index 0e0847c..5c92825 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -46,7 +46,7 @@ proxy listens on `3333`). The interactive first-run setup writes exactly this mi | Key | Default | What it does | |---|---|---| -| `pools` | _(required)_ | XMRig's native pools array — the pool(s) to mine to. Each entry needs a `url` (`host:port`); every other field falls back to a Pithead default. A pool's `user` is the rig's dashboard label (defaults to the hostname). List multiple entries for failover. See [Pools](#pools-full-control). | +| `pools` | *(required)* | XMRig's native pools array — the pool(s) to mine to. Each entry needs a `url` (`host:port`); every other field falls back to a Pithead default. A pool's `user` is the rig's dashboard label (defaults to the hostname). List multiple entries for failover. See [Pools](#pools-full-control). | | `ACCESS_TOKEN` | the rig name (first pool's `user`) | The XMRig HTTP API bearer token. Leave it unset so it defaults to the rig name — **Pithead authenticates as `Bearer `**, so the token must equal the rig name (or be unset). See [Pithead Integration](pithead-integration.md). | | `DONATION` | `1` | XMRig donate level, an integer **0–100** (percent). Patched into the build (`donate.h`) **and** written to the generated config, so it must be a valid integer or setup fails fast. | | `HOME_DIR` | `DYNAMIC_HOME` | Where worker files live. `DYNAMIC_HOME` puts them in `data/worker` inside the repo; set an absolute path to use `/worker` instead. | @@ -90,7 +90,7 @@ what you care about: | Field | Default if blank/omitted | |---|---| -| `url` | _(required)_ — `host:port` (e.g. `pool.supportxmr.com:443` or `your-stack:3333`). For an IPv6 literal, use the bracketed `[2001:db8::1]:3333` form. | +| `url` | *(required)* — `host:port` (e.g. `pool.supportxmr.com:443` or `your-stack:3333`). For an IPv6 literal, use the bracketed `[2001:db8::1]:3333` form. | | `user` | the machine hostname. For **Pithead** this is just the rig's dashboard **label**; for a **public pool** set it to your **Monero wallet address** (see below). | | `pass` | `"x"` — the stratum password / worker name. For an **open** Pithead stack the default works; if the operator enabled the stack's `p2pool.stratum_password`, set this to that secret or the proxy rejects the rig. See [Pithead Integration › Stratum authentication](pithead-integration.md#stratum-authentication-optional). | | `keepalive` | `true` | diff --git a/docs/getting-started.md b/docs/getting-started.md index 60997a8..5462709 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,12 +4,14 @@ This guide takes you from a fresh machine to a tuned, running XMRig worker. The driven by a single script — `rigforge.sh` — and most of it is automated. > **TL;DR** +> > ```bash > git clone https://github.com/p2pool-starter-stack/rigforge.git > cd rigforge > chmod +x rigforge.sh > sudo ./rigforge.sh > ``` +> > Answer one prompt (your pool URL), let it build, and — on Linux — reboot once to apply the > kernel tuning. The `xmrig` service starts automatically after the reboot. diff --git a/docs/how-it-works.md b/docs/how-it-works.md index 56efdd0..9f15032 100644 --- a/docs/how-it-works.md +++ b/docs/how-it-works.md @@ -120,14 +120,14 @@ Every part of the search is overridable; the defaults favour a thorough one-time | `TUNE_SEEDS` | `auto guess` | Starting points to climb from. | | `TUNE_PREFETCH_MODES` | `0 1 2 3` | Prefetch-mode candidates. | | `TUNE_YIELDS` | `true false` | `cpu.yield` candidates. | -| `TUNE_THREADS` | _(auto: SMT-aware set)_ | `cpu.rx` thread-count candidates. Defaults to auto + physical/logical cores + an L3 window; override with an explicit list. | +| `TUNE_THREADS` | *(auto: SMT-aware set)* | `cpu.rx` thread-count candidates. Defaults to auto + physical/logical cores + an L3 window; override with an explicit list. | | `TUNE_PRIORITIES` | `2` | `cpu.priority` candidates (single value ⇒ knob off; set e.g. `1 2 3 4 5` to sweep). | -| `TUNE_HPJIT` | _(off)_ | Set `false true` to sweep `cpu.huge-pages-jit` (XMRig: small Ryzen boost, unstable hashrate). | -| `TUNE_CACHEQOS` | _(off)_ | Set `false true` to sweep `randomx.cache_qos` (Intel L3 Cache Allocation Technology). | -| `TUNE_WRMSR` | _(off)_ | Sweep the `randomx.wrmsr` MSR preset, e.g. `true false` (or a preset number). Rarely needed — XMRig auto-picks the right preset; set this only to confirm it on unusual hardware. Applied per-bench, no reboot. | -| `TUNE_POWER_CMD` | _(RAPL)_ | Override the power source with a shell command that echoes **instantaneous watts** (IPMI, a smart plug, wall-AC). Without it, the built-in CPU-package RAPL reader is used on Linux. | -| `TUNE_TARGET` | _(follows `autotune` config)_ | Optimize for `perf` (raw H/s) or `efficiency` (hashrate-per-watt). Defaults to the `autotune` config value (so a manual `tune` matches the scheduled run); `--perf`/`--efficiency` or this env var override. Efficiency needs a power source or falls back to `perf`. | -| `TUNE_TEMP_CMD` | _(Linux thermal zone)_ | Optional shell command that echoes °C; defaults to `/sys/class/thermal/thermal_zone0/temp`. | +| `TUNE_HPJIT` | *(off)* | Set `false true` to sweep `cpu.huge-pages-jit` (XMRig: small Ryzen boost, unstable hashrate). | +| `TUNE_CACHEQOS` | *(off)* | Set `false true` to sweep `randomx.cache_qos` (Intel L3 Cache Allocation Technology). | +| `TUNE_WRMSR` | *(off)* | Sweep the `randomx.wrmsr` MSR preset, e.g. `true false` (or a preset number). Rarely needed — XMRig auto-picks the right preset; set this only to confirm it on unusual hardware. Applied per-bench, no reboot. | +| `TUNE_POWER_CMD` | *(RAPL)* | Override the power source with a shell command that echoes **instantaneous watts** (IPMI, a smart plug, wall-AC). Without it, the built-in CPU-package RAPL reader is used on Linux. | +| `TUNE_TARGET` | *(follows `autotune` config)* | Optimize for `perf` (raw H/s) or `efficiency` (hashrate-per-watt). Defaults to the `autotune` config value (so a manual `tune` matches the scheduled run); `--perf`/`--efficiency` or this env var override. Efficiency needs a power source or falls back to `perf`. | +| `TUNE_TEMP_CMD` | *(Linux thermal zone)* | Optional shell command that echoes °C; defaults to `/sys/class/thermal/thermal_zone0/temp`. | ### Power & efficiency diff --git a/docs/operations.md b/docs/operations.md index 6d40e36..6dfed08 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -32,13 +32,13 @@ reference](#commands) is below. The complete surface — most days you only need the handful in [Common tasks](#common-tasks) above; the rest are here for completeness. -RigForge is a single script. Run it as `sudo ./rigforge.sh [command]`. _(Optional: set +RigForge is a single script. Run it as `sudo ./rigforge.sh [command]`. *(Optional: set `"add_to_path": true` in `config.json` and setup installs a `rigforge` command on your PATH, so you can -run `sudo rigforge [command]` from any directory; `uninstall` removes it.)_ +run `sudo rigforge [command]` from any directory; `uninstall` removes it.)* | Command | What it does | |---|---| -| `setup` _(default)_ | Provision the worker: dependencies, build, hardware + kernel tuning, and the service. Idempotent — safe to re-run; skips the recompile when the pinned XMRig is already built. | +| `setup` *(default)* | Provision the worker: dependencies, build, hardware + kernel tuning, and the service. Idempotent — safe to re-run; skips the recompile when the pinned XMRig is already built. | | `upgrade` | Rebuild **and** restart **only if** the pinned XMRig version/commit changed. A no-op when you're already on the pinned build. If periodic autotune is enabled, it also **re-tunes the new build** (the fastest knobs can shift between versions). | | `apply` | Re-read `config.json`, regenerate the live XMRig config, and restart — **without** recompiling. The fast path after editing `config.json`. On Linux it also reconciles the periodic-autotune timer with config (so changing the `autotune` target takes effect) and reports it (efficiency / performance / disabled). | | `uninstall` | Remove the service and **revert all system changes** (fstab, limits, modules, GRUB) and the worker build/logs. Leaves `config.json`. Prompts first; add `--yes` to skip. | @@ -132,7 +132,7 @@ Prefer it hands-off? Set `autotune` in `config.json` to a target and re-run `set | `autotune` | What the scheduled run optimizes for | | --- | --- | -| `"disabled"` _(default)_ | Nothing — no timer is installed. | +| `"disabled"` *(default)* | Nothing — no timer is installed. | | `"performance"` | **Raw hashrate** (H/s). | | `"efficiency"` | **Hashrate-per-watt** (H/s/W) — for power-cost-, heat-, or PSU-limited rigs. Needs a power source (built-in RAPL, or a `TUNE_POWER_CMD` for a smart plug / IPMI); without one it falls back to `performance` with a warning. |