Skip to content

Keep RigForge in control of generated XMRig config - #608

Merged
pithead-reviewer[bot] merged 12 commits into
developfrom
astra/529-rigforge
Nov 14, 2026
Merged

pithead-reviewer[bot] merged 12 commits into
developfrom
astra/529-rigforge

Conversation

@pithead-developer

@pithead-developer pithead-developer Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

What's the problem

XMRig can rewrite and hot-reload the config RigForge generates. Disabling those defaults alone
would strand config edits on an already-built appliance worker: setup previously only started
the service, which does not reload a running miner.

Closes #529

How I fixed it

  • Generate autosave: false and watch: false.
  • Compare generated-config SHA-256 values around setup's render and restart when they differ,
    including when no rebuild is needed. An unchanged setup still ensures the service is started;
    reboot deferral and caller-owned restart guards retain precedence.
  • Update operator documentation, setup's dry-run description, and the affected expectations.
    Add isolated regressions to the main suite and the pinned Linux container runner.

Doctor/apply-stamp changes remain in #445 and general overlay opt-back-in remains in #526,
as directed by the owner. This addresses #529 without changing versions or file permissions.

Here is the proof

The new regression suite exercises real setup, config generation, and service installation with
privileged actions stubbed in a disposable directory. It covers fresh and existing configs,
unchanged reruns, a one-byte edit, legacy defaults, inactive services, reboot deferral, and failures.

Commands executed before and after the production fix:

baseline_dir=$(mktemp -d); git show HEAD:rigforge.sh > "$baseline_dir/rigforge.sh"; bash tests/test-config-ownership.sh "$baseline_dir/rigforge.sh"
bash tests/test-config-ownership.sh

The pristine script returned exit 1: 14 passed, 8 failed. The fixed script returned exit 0:
22 passed, 0 failed. The baseline scratch directory was removed afterward.

Completed checks:

  • PATH=/private/tmp/rigforge-529-tools/bin:$PATH make test — exit 0: 2431 passed, 0 failed
    in the main suite; contract credentials, access-token readiness, docs clone pins, and tool-pin
    watcher suites also passed.
  • PATH=/private/tmp/rigforge-529-tools/bin:$PATH make lint — exit 0 using repository-pinned
    shfmt 3.14.1 and ShellCheck 0.11.0; includes topology and file-budget gates.
  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh — exit 0.
  • shellcheck --severity=warning tests/test-config-ownership.sh — exit 0.
  • /private/tmp/rigforge-529-tools/bin/shfmt -i 4 -d tests/test-config-ownership.sh — exit 0.
  • make test-e2e — exit 0 in the repository's digest-pinned Linux container: 88 standard +
    28 appliance assertions passed
    , plus all 22 ownership regressions in each pass.
  • npm_config_cache=/private/tmp/rigforge-529-tools/npm-cache npx --yes markdownlint-cli2@0.23.3 --no-globs docs/configuration.md docs/operations.md PR-BODY.md
    — exit 0, no issues in the two changed documents or this proof file.
  • git diff --check — exit 0.

Initial make test stopped at formatting because the installed shfmt 3.13.1 disagreed with the
repository's pinned version on existing lines. The pinned lint run above passed.
npm_config_cache=/private/tmp/rigforge-529-tools/npm-cache make lint-md returned exit 2 solely
for four formatting errors in the supplied, unchanged ISSUE.md. A retry with
npm_config_cache=/private/tmp/rigforge-529-tools/npm-cache npx --yes markdownlint-cli2@0.23.3 '!ISSUE.md'
still included that file because of the configured globs; the explicit changed-document check
above passed.

The first make test-suite run completed with 2430 passed, 1 failed (make exit 2): the
existing appliance dry-run assertion still expected unconditional enable --runtime --now.
It now strictly checks the new conditional restart/start/reboot wording required by this issue,
and the final make test run above passed.
The Mac suite explicitly skips Linux-only tuning timing tests.

A diagnostic timeout -k 5 60 bash tests/test-control-replay.sh returned 124 before that
CPU-heavy matrix finished; the complete replay matrix subsequently passed in the full suite.

Merged develop-v1.19.0 (one main() declaration conflict). Merged current origin/develop for mergeability: the service restart condition became rebuild || shared-host || config-changed, the re-own helper keeps develop's Linux early return and shared-host log handling under the same MINER_USER guard, and the main() locals, the e2e-pithead.sh source lines, phase dispatch and phase lists, and the docs list item are unions of both sides; targeted suites re-run on the merged head (test-config-ownership.sh 22/22, test-e2e-config-ownership.sh 18/18, test-config-apply-state.sh, test-shared-host.sh, test-randomx-mode.sh) pass and the file-budget gate exits 0. Earlier GitHub reds, fixed: tests/test-sister-reconcile.sh stubs generate_xmrig_config, so the after-hash of a missing config.json aborted main() under set -e (now guarded like the before-hash); diff-cover missed the two jq-literal lines autosave/watch (now set on the already-covered render line, rigforge.sh:1179). Local make lint fails on 7 shfmt hunks in tests/run.sh that the base has too.

Live proof (reviewer finding on rigforge.sh:1179, rigforge.sh:1270): a new explicit tier4-e2e phase, config-ownership (tests/e2e-config-ownership.sh, not in all), regenerates the config with the miner stopped, then requires (1) autosave=false/watch=false and byte-identical generated bytes after the miner is live plus 30 s; (2) a hand donate-level edit of the generated file to leave the PID and reported donate_level unchanged for 20 s, with a restart then loading it as the positive control; (3) setup on an already-built worker to log "recompile will be skipped" and "Restarting XMRig service", change the PID, render a toggled pool keepalive, keep the binary hash and go live again. The phase refuses to run setup (row red, plan lines quoted) when setup --dry-run plans a rebuild, a package install, a GRUB change or a reboot. The keepalive toggle is written only to $CFG, which the harness _cleanup restores. tests/test-e2e-config-ownership.sh (in make test-suite) drives the phase against stubs: the pass path and nine failure modes each produce the expected row and the guarded modes never run setup.

Bench proof, tier4-e2e job 3994 on head c149e6e (phases=connect,config-ownership, base develop), green: all four config-ownership rows passed on the rig — autosave/watch off, the generated config byte-identical while mining, a hand edit not hot-reloaded until a restart loads it, and setup on the already-built worker restarting the miner with a changed pool keepalive and an unchanged binary. _cleanup restored the rig (rig restored: yes). The earlier job 3985 passed identically on the pre-merge head 2c0c4fd.

bench-ci job 3994@c149e6e3227e81e5e20c26f6e11578225f670474 · rigforge · tier4-e2e

  • options: {"phases": ["connect", "config-ownership"]}
  • status: completed · conclusion: success · exit 0 · 4m 34s
  • baseline verified: yes · rig restored: yes
  • node guard: not recorded · no comparison recorded
  • steps: checkout success · reserve success · preflight success · run success · collect success · restore success · cleanup success
  • rows: 12 pass · 0 fail · 0 skip
    Generated by bench-ci evidence 3994@c149e6e3227e81e5e20c26f6e11578225f670474; re-run it to check.

The head is a base merge of origin/develop through 910f107 (the validated xmrig overlay): the two doc/README conflicts resolved keeping this PR's autosave: false, watch: false render item and config-ownership rows alongside the overlay docs. tests/test-xmrig-overlay.sh fails 7 of 77 identically on pristine origin/develop on this host (macOS; develop's own CI runs it green on Linux).

Current head f302c94 merges origin/develop through d225dd8 (#693, plain XMRig logging). The render conflict keeps both sides in one object: {autosave: false, watch: false, "print-time": 60, "health-print-time": 60} plus Linux-only colors: false; docs/configuration.md item 3 lists all of them. Develop filled tests/run.sh to its file-budget ceiling, so the overlay, logging and config-ownership suites now run in one run.sh loop, and tests/test-config-ownership.sh chains test-e2e-config-ownership.sh (run even when a unit check fails, exit non-zero if either fails; checked by injecting a unit failure: rc 1, e2e rows still printed). On this head: FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh OK; tests/test-config-ownership.sh 22/22 + e2e 18/18, test-xmrig-logging.sh 11/11, test-config-apply-state.sh, test-shared-host-lifecycle.sh, test-worker-proof.sh pass locally; all ten GitHub checks pass (Test suite, Coverage, End-to-end (Docker), lints). Bench proof on the current head: tier4-e2e job 4002 on f302c94 (phases=connect,config-ownership, base develop, fleet-routed) succeeded; job 3994 above is on the previous head.

bench-ci job 4002@f302c942ac11999a9261658fbc196b8ef93b8e6a · rigforge · tier4-e2e

  • options: {"phases": ["connect", "config-ownership"]}
  • status: completed · conclusion: success · exit 0 · 4m 57s
  • baseline verified: yes · rig restored: yes
  • node guard: not recorded · no comparison recorded
  • steps: checkout success · reserve success · preflight success · run success · collect success · restore success · cleanup success
  • rows: 14 pass · 0 fail · 0 skip
    Generated by bench-ci evidence 4002@f302c942ac11999a9261658fbc196b8ef93b8e6a; re-run it to check.

Not covered: reboot-deferred setup on real hardware, and the least-privilege follow-up that _reown_worker still gives MINER_USER write access to xmrig/build/config.json (rigforge.sh:1812); this PR leaves file permissions unchanged.

Draft from an operator-run gpt-6-astra session (owner request, 2026-11-01). The operator reviews and gates it before it leaves draft.

🤖 Generated with Claude Code

Part of #529. Implemented by an operator-run gpt-6-astra session at the owner's request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added the operator-action Needs the operator's hands, not an answer: nothing waits on it and no ruling clears it label Nov 2, 2026
@pithead-developer

Copy link
Copy Markdown
Contributor Author

Operator: this v2.x enhancement stays a held draft until RigForge 1.18.1 is tagged (due Fri 2026-11-06, Sat 11-07 at the latest). 1.18.1 is cut from develop, so merging this first would widen that release. After the tag: rebase on develop, run the agent review, and request the owner's approval.

@pithead-developer pithead-developer Bot added this to the v2.x - post-GA milestone Nov 2, 2026
@pithead-developer pithead-developer Bot added the stage/operator parked for the operator label Nov 2, 2026
@pithead-developer pithead-developer Bot removed the operator-action Needs the operator's hands, not an answer: nothing waits on it and no ruling clears it label Nov 6, 2026
@pithead-developer

Copy link
Copy Markdown
Contributor Author

Operator: released to the runner (owner 2026-11-06). New work goes to the local Flash-Next model first; Claude only after three local rounds or for sensitive work.

@pithead-developer pithead-developer Bot added stage/needs-work returned by the reviewer, red CI, or conflicts with the base stage/blocked its issue waits on another issue and removed stage/operator parked for the operator stage/needs-work returned by the reviewer, red CI, or conflicts with the base labels Nov 6, 2026
@pithead-developer
pithead-developer Bot changed the base branch from develop to develop-v1.19.0 November 7, 2026 07:07
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/needs-work returned by the reviewer, red CI, or conflicts with the base and removed stage/blocked its issue waits on another issue labels Nov 7, 2026
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/in-progress stage/needs-check and removed stage/needs-work returned by the reviewer, red CI, or conflicts with the base stage/in-progress stage/needs-check labels Nov 7, 2026
pithead-developer[bot] and others added 2 commits November 7, 2026 02:41
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@pithead-reviewer

Copy link
Copy Markdown
Contributor

FAIL

What I investigated

Reviewed PR #608 at head ef155c2 against issue #529 and the owner's 2026-10-06 ruling on it. The scope is correct. The fix does what it claims: the new regression test is red at base (14 passed, 8 failed) and green at head (22 passed, 0 failed), and all GitHub checks pass. The PR changes config rendering in generate_xmrig_config and the systemd restart decision in install_service, but no bench-ci tier4-e2e job exists on the head. The PR body itself lists that proof as still needed.

  • gh pr checks 608 --json: all 10 checks SUCCESS at head ef155c2 (Test suite, Coverage kcov + diff-cover, End-to-end (Docker), shellcheck + shfmt, markdownlint, yamllint, gitleaks, zizmor, Stock home setup current and historical); none skipped

  • bash tests/test-config-ownership.sh (head) -> rc=0, 'config ownership tests: 22 passed, 0 failed'

  • bash tests/test-config-ownership.sh with the base rigforge.sh from origin/develop-v1.19.0 -> rc=1, '14 passed, 8 failed' (autosave/watch values and the six restart assertions fail); this matches the PR body

  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh -> rc=0, 'file budget OK'

  • make lint-topology -> rc=0, 'topology classes OK'

  • detect-topology.py over the PR Keep RigForge in control of generated XMRig config #608 body, the PR Keep RigForge in control of generated XMRig config #608 comments and the issue XMRig rewrites and hot-reloads the config RigForge owns: autosave is forced on and watch is left at its default #529 comments -> 'clean' x3

  • bench-ci list --all --fleet --repo rigforge --commit ef155c2 -> 'completed 0', no jobs

  • Read rigforge.sh:962: on the no-rebuild path compile_xmrig changes into $WORKER_ROOT/xmrig/build, so main's config.json before/after hash (rigforge.sh:1993-1996) covers the generated config, not the operator's source config

  • git log: origin/develop and origin/develop-v1.19.0 both at b1c25d6, and the head contains the base

  • gh pr view 608 --json baseRefName -> develop-v1.19.0: The base is develop-v1.19.0, not develop as CLAUDE.md says. Both currently point at b1c25d6, and the operator's comment on the PR covers retargeting after the 1.18.1 tag. This is for the operator, not a defect.

  • rigforge.sh:1812: _reown_worker still gives MINER_USER ownership of xmrig/build/config.json. That write access existed only for autosave, which is now off, so it could be removed as a least-privilege follow-up. The PR body deliberately leaves file permissions unchanged, so this does not block.

Reviewed head: ef155c2269bcfb85d83231d800c83503d0e7dd7e.

What are the gaps

  • rigforge.sh:1179, rigforge.sh:1270 (bench-ci list --all --fleet --repo rigforge --commit ef155c2… -> 0 jobs): The diff changes how the XMRig config is rendered (autosave and watch are now false) and when systemd restarts the miner (setup now restarts it when the generated config hash changes). Rule 8 (tier follows the path) requires a tier4-e2e job (targeted or matrix) that built and deployed this exact head on a rig. None exists, and the PR body's 'Still needed' paragraph admits it. Submit one on the head and quote its evidence block. It should show: (1) the generated config stays byte-identical while mining (no autosave write-back); (2) a hand edit is not hot-reloaded; (3) setup on an already-built appliance worker restarts xmrig.service and applies a changed pool setting without a rebuild.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/bench-testing its issue waits on a queued or running tier-4 bench job stage/in-progress and removed stage/in-progress stage/bench-testing its issue waits on a queued or running tier-4 bench job labels Nov 14, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

PASS

What I investigated

Re-review of PR #608 (issue #529: RigForge owns the generated XMRig config; autosave/watch off, and setup restarts the miner when the generated config changes). Since the last reviewed head 2c0c4fd, the only change is a merge of develop (#604, XMRig overlays) into c149e6e. That merge's conflict resolutions touch only docs and keep both sides. The one standing return was the missing tier4-e2e proof. It is now closed: bench-ci job 3994 ran on head c149e6e with phases connect and config-ownership, concluded success, and passed 12 of 12 rows. Those rows include no autosave write-back, no hot reload of a hand edit, and setup restarting the miner without a rebuild. CI is green, the new unit tests pass, the file budget is OK and topology is clean.

  • git cat-file -e 2c0c4fd -> present. git log --no-merges 2c0c4fd..c149e6e -> only 910f107 (Add validated XMRig configuration overlays #604, from develop). The worker made no code commits since the last review.

  • git show --remerge-diff c149e6e -> the conflicts were only in docs/configuration.md and tests/README.md. The resolutions keep XMRig rewrites and hot-reloads the config RigForge owns: autosave is forced on and watch is left at its default #529's ownership text plus Add validated XMRig configuration overlays #604's xmrig-object mention, and Add validated XMRig configuration overlays #604's overlay row plus XMRig rewrites and hot-reloads the config RigForge owns: autosave is forced on and watch is left at its default #529's config-ownership phase description. No code was hand-resolved.

  • bench-ci list --all --fleet --repo rigforge --commit c149e6e -> job 3994, tier4-e2e, completed, success

  • bench-ci evidence 3994@c149e6e3227e81e5e20c26f6e11578225f670474 -> phases [connect, config-ownership], conclusion success, exit 0, baseline verified yes, rig restored yes, all steps success, 12 pass / 0 fail / 0 skip. diff against PR body lines 76-83 -> BLOCK_IDENTICAL

  • bench-ci log 3994 -> checkout at c149e6e; connect 8 ok; config-ownership 4 ok: 'generated config sets autosave=false and watch=false', 'stays byte-identical while the miner mines', 'hand edit ... is not hot-reloaded (same PID, donate_level unchanged) and a restart loads it', 'setup on an already-built worker applies a changed pool setting with a restart and no rebuild'. The rig was restored and the live stack was healthy afterwards.

  • Read tests/e2e-config-ownership.sh: the rows are real assertions. They compare sha256 before and after a 30 s mining window, check that the PID and the API donate_level stay unchanged after a hand edit, and check that the PID changes, the keepalive change lands and the binary sha is unchanged after setup. None of them is a health-only check.

  • Round-2 finding [return] rigforge.sh:1179/1270 (no tier4-e2e on head): FIXED by job 3994 on c149e6e (above).

  • Round-2 finding [return] rigforge.sh:1257 (3493 red on own row 'setup --dry-run plans a rebuild'; no job on head): FIXED. Job 3994's setup row passed on the head, so the rig is now in an already-built state.

  • Round-2 note base develop-v1.19.0: CLOSED. gh pr view 608 --json baseRefName -> develop

  • Round-2 note PR body bench proof stale: FIXED. Body line 74 now cites job 3994 on c149e6e, and the 'Still unproven' text is gone.

  • Round-2 note _reown_worker least-privilege (rigforge.sh ~1812): carried as a note. Unchanged and non-blocking.

  • gh pr checks 608 --json -> 10/10 pass: Test suite, Coverage (kcov + diff-cover), End-to-end (Docker), Lint shellcheck+shfmt, yamllint, markdownlint, zizmor, gitleaks, Stock home setup current/historical

  • bash tests/test-config-ownership.sh ./rigforge.sh -> exit 0, 22 passed, 0 failed. bash tests/test-e2e-config-ownership.sh -> exit 0, 18 passed, 0 failed

  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh -> 'file budget OK', exit 0

  • detect-topology.py over the PR body, PR comments and issue XMRig rewrites and hot-reloads the config RigForge owns: autosave is forced on and watch is left at its default #529 comments -> 'clean', exit 0

  • Comment discipline: the rigforge.sh hunks delete the stale autosave explanation and add no comments. The new test file adds only a '# shellcheck shell=bash' directive.

  • rigforge.sh:1812: Carried from round 2: _reown_worker still gives MINER_USER write access to xmrig/build/config.json. That access was only needed for autosave, which is now off. Removing it is a least-privilege follow-up and does not block.

  • util/xmrig-overlay-keys.jq:6 (from Add validated XMRig configuration overlays #604, merged via develop): The Add validated XMRig configuration overlays #604 overlay allowlist includes 'autosave' and 'watch', and _merge_xmrig_overlay (rigforge.sh:1178) runs after this PR's {autosave:false, watch:false}. An operator can therefore opt back into XMRig rewriting or hot-reloading the generated config. That is a deliberate operator override, not a defect in this PR. docs/configuration.md could say that it gives up the ownership guarantee.

Reviewed head: c149e6e3227e81e5e20c26f6e11578225f670474.

@pithead-reviewer
pithead-reviewer Bot marked this pull request as ready for review November 14, 2026 17:30
@pithead-developer pithead-developer Bot added stage/awaiting-merge the reviewer's PASS is on the head; merging when checks and the base allow and removed stage/in-progress labels Nov 14, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

Owner brief for c149e6e3227e

What it does. The XMRig config that RigForge generates now has autosave and watch turned off. XMRig no longer writes its own settings back into the file, and it no longer reloads hand edits live. Running setup on an already-built Linux worker now restarts the miner when the generated config changed, and it only starts the service if nothing changed.

Why. Closes #529 (milestone v1.19.0). Before, XMRig rewrote the generated file and hot-reloaded edits, so the file on disk was not what RigForge generated. That also made later "does the live config match" checks noisy. Turning the keys off alone would have left existing workers on the old config, because setup never restarted a running miner. That is why the restart-on-change logic is included.

Risk. Low. A setup re-run on a built Linux worker can now restart a running miner, but only when the config hash changed. Existing workers will see one restart on their first setup, because the legacy config differs. Reboot deferral and caller-owned restart guards still take precedence. Operators can opt back in through the overlay allowlist, which includes autosave and watch (from #604). No version or permission changes.

Proof. CI: 11 success. Reviewer: PASS at c149e6e by pithead-reviewer, round 3 (recorded 2026-11-14T17:30:17Z). Bench: job 3994: success on the head.

What to check.

  • rigforge.sh:2006-2009 and rigforge.sh:1261: the before/after SHA-256 comparison around config generation and the XMRIG_CONFIG_CHANGED restart condition. Check that a missing config.json cannot abort main() under set -e.
  • rigforge.sh:1171: {autosave: false, watch: false} is appended after the optional log-file merge. The overlay and tune merges run later, so an operator can still override it.
  • docs/configuration.md: the overlay note could say that re-enabling autosave or watch gives up the ownership guarantee. The reviewer suggested this as an optional improvement.
  • rigforge.sh:1812: _reown_worker still gives the miner user write access to config.json, which was only needed for autosave. This is a least-privilege follow-up and not a blocker.

Verdict. merge

VijitSingh97
VijitSingh97 previously approved these changes Nov 14, 2026
@pithead-developer pithead-developer Bot added stage/in-progress and removed stage/awaiting-merge the reviewer's PASS is on the head; merging when checks and the base allow labels Nov 14, 2026
Keep autosave:false and watch:false beside develop's print-time,
health-print-time and Linux colors:false render defaults, and run the
config-ownership suites through the shared run.sh loop so tests/run.sh
stays under its file-budget ceiling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/bench-testing its issue waits on a queued or running tier-4 bench job stage/in-review a reviewer session is on it now and removed stage/in-progress stage/bench-testing its issue waits on a queued or running tier-4 bench job labels Nov 14, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

PASS

What I investigated

I re-reviewed PR #608 (issue #529) at head f302c94, starting from the last reviewed head 2c0c4fd, which is present in this clone. Since that head, the worker made one commit: tests/test-config-ownership.sh now runs the e2e stub rows even when a unit check fails. The rest arrived through two merges from develop (#604, #693). The resolution keeps {autosave: false, watch: false, "print-time": 60, "health-print-time": 60} in a single render object, plus colors false on Linux. The blocking rule-8 finding is fixed: tier4-e2e job 4002 ran phases=connect,config-ownership on f302c94 and succeeded, and I re-derived its evidence and log myself. All ten GitHub checks pass on the head, the local regression and file-budget gates pass, and topology is clean. The branch has no commits behind develop and the base is now develop.

  • git cat-file -e 2c0c4fd -> present; git log --no-merges 2c0c4fd..f302c94 -> f302c94 (worker, tests/test-config-ownership.sh, 1 line) plus develop's 910f107 and d225dd8 through merges

  • git merge-base origin/develop HEAD == origin/develop == d225dd8 -> no commits behind; gh pr view baseRefName -> develop (round-2 base note closed)

  • bench-ci evidence 4002@f302c942ac11999a9261658fbc196b8ef93b8e6a -> completed, success, exit 0, baseline verified yes, rig restored yes, all steps success, rows 14 pass 0 fail 0 skip; identical to the block pasted in the PR body

  • bench-ci log 4002 -> checks out f302c94 into the install tree; connect 10 ok; config-ownership 4 ok: autosave=false/watch=false; config byte-identical while mining; hand edit not hot-reloaded (same PID, donate_level unchanged) and a restart loads it; setup on an already-built worker applies a changed pool setting with a restart and no rebuild; checkout restored and re-applied, live stack healthy

  • Earlier finding round 2 [return] rigforge.sh:1179/1270 + rigforge.sh:1257 (no tier4-e2e on head): FIXED by job 4002 on the current head; its rows cover byte-identity, no hot reload, and setup restart without rebuild

  • Earlier note: base develop-v1.19.0: CLOSED; base is now develop

  • Earlier note: _reown_worker MINER_USER write access (rigforge.sh:1812): still present; the PR body discloses it under 'Not covered'; a note, as ruled

  • Earlier note: refresh the body's bench block: FIXED; the body quotes 4002@f302c94 as current, and the 3994 block is labelled as the previous head

  • gh pr checks 608 --json -> 10/10 SUCCESS (Test suite, Coverage kcov+diff-cover, End-to-end Docker, shellcheck+shfmt, yamllint, markdownlint, gitleaks, zizmor, stock home setup current/historical)

  • bash tests/test-config-ownership.sh -> rc 0: 22 passed 0 failed; e2e config-ownership phase tests 18 passed 0 failed

  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh -> rc 0 'file budget OK'

  • make lint-topology -> rc 0

  • detect-topology.py over the PR body, PR comments, PR reviews, PR review comments and issue XMRig rewrites and hot-reloads the config RigForge owns: autosave is forced on and watch is left at its default #529 comments -> rc 0 on every file

  • git diff origin/develop...f302c94, added comment lines in code -> only shellcheck directives (functional, kept); the stale 'Deliberately NOT gated' rationale in rigforge.sh is deleted, not edited

  • Read the f302c94 logic: 'bash test-e2e-config-ownership.sh && [ "$FAIL" -eq 0 ]' always runs the e2e rows and exits non-zero if either part fails; run.sh registers it in the suite loop and in-container.sh runs it under || exit 1

  • rigforge.sh:1812: Carried from earlier rounds: _reown_worker still gives MINER_USER write access to xmrig/build/config.json. With autosave off, that access is no longer needed. This is a least-privilege follow-up, and the PR body already discloses it.

  • PR body, last paragraph: The body still says 'Draft from an operator-run ... session ... before it leaves draft', but the PR is no longer a draft. It also keeps the superseded 3994 evidence block. Trim both when the body is next touched.

  • util/xmrig-overlay-keys.jq (develop's Add validated XMRig configuration overlays #604): Develop's overlay already allowlists autosave and watch, so an operator can turn them back on today. The 'overlay can flip them' test belongs to No way to set an XMRig key RigForge does not map: add an xmrig overlay to config.json, validated with xmrig --dry-run #526 under the owner's ruling. No test on this head covers that flip.

Reviewed head: f302c942ac11999a9261658fbc196b8ef93b8e6a.

@pithead-reviewer

Copy link
Copy Markdown
Contributor

Owner brief for f302c942ac11

What it does. The generated XMRig config now sets autosave and watch to false, so XMRig no longer writes back into the file or hot-reloads hand edits. On Linux, a full setup re-run on an already-built worker now restarts the miner when the generated config's hash changed, even with no rebuild. An unchanged re-run only makes sure the service is started. A pending reboot still defers the start.

Why. Closes #529 (milestone v1.19.0). Before, autosave was forced on and watch was left at XMRig's default of on. The file on disk drifted from what RigForge generated, and hand edits took effect live with nothing recording them. Turning those off alone would have left already-built workers on the old config, because setup only started the service and never restarted it.

Risk. Low. The one behaviour change is that setup may now restart a running miner on Linux when the config changed. That is the intended behaviour. The first setup after upgrading will restart once, because old configs have autosave on and no watch key. Operators who set autosave or watch back on through the xmrig overlay (allowed by #604) give up the ownership guarantee, and no test on this head covers that. Nothing is irreversible.

Proof. CI: 11 success. Reviewer: PASS at f302c94 by pithead-reviewer, round 3 (recorded 2026-11-14T20:27:11Z). Bench: job 3994: success on c149e6e, not the head; job 4002: success on the head.

What to check.

  • rigforge.sh:1262 and rigforge.sh:2007-2010: the restart condition now includes the config-changed flag, and the before/after hashes are guarded when config.json is missing. Confirm that reboot deferral and the caller-owned restart guard still take precedence.
  • rigforge.sh:1172: autosave and watch are set in the same render object as the print-time keys, so they come before the overlay and tune merges. This is why the overlay can still flip them.
  • tests/e2e-config-ownership.sh:84-100: the live phase refuses to run setup if the dry-run plans a rebuild, package install, GRUB change or reboot. Check that guard is strict enough for a real rig.
  • tests/run.sh:45: three test scripts are now run from a loop. The PR notes that shfmt already complains about hunks in this file on the base.

Verdict. merge

@pithead-developer pithead-developer Bot added stage/awaiting-merge the reviewer's PASS is on the head; merging when checks and the base allow and removed stage/in-review a reviewer session is on it now labels Nov 14, 2026
@pithead-reviewer
pithead-reviewer Bot merged commit 2413891 into develop Nov 14, 2026
11 checks passed
@pithead-reviewer
pithead-reviewer Bot deleted the astra/529-rigforge branch November 14, 2026 22:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stage/awaiting-merge the reviewer's PASS is on the head; merging when checks and the base allow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XMRig rewrites and hot-reloads the config RigForge owns: autosave is forced on and watch is left at its default

1 participant