Skip to content

Keep RigForge in control of generated XMRig config - #608

Draft
pithead-developer[bot] wants to merge 8 commits into
developfrom
astra/529-rigforge
Draft

pithead-developer[bot] wants to merge 8 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). 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 3493 on head 49dc9fe (phases=connect,config-ownership, base develop-v1.19.0), red: the first three config-ownership rows passed on the rig (autosave/watch false, byte-identical while mining, hand edit not hot-reloaded and loaded by a restart), but the setup-restart proof did not run, because setup --dry-run on the rig planned a rebuild (the rig's XMRig build does not satisfy xmrig_already_built; most likely it predates the zero-donation marker from #603, inferred, not read from the rig). By the operator's ruling the phase refuses to run setup there and the rig needs its state fixed before a re-run. _cleanup restored the rig (rig restored: yes).

bench-ci job 3493@49dc9fe5dd76f627f6032b45ba3a2a2af9568db2 · rigforge · tier4-e2e

Still unproven live: setup restarting the miner with a changed pool setting and no rebuild; the stub test tests/test-e2e-config-ownership.sh covers that logic only.

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 Opus 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/question its issue has a question pending and removed stage/in-progress labels Nov 7, 2026
…a reboot

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/in-progress stage/bench-testing its issue waits on a queued or running tier-4 bench job stage/operator parked for the operator and removed stage/question its issue has a question pending stage/in-progress stage/bench-testing its issue waits on a queued or running tier-4 bench job labels Nov 7, 2026
@pithead-developer pithead-developer Bot modified the milestones: v2.x - post-GA, v1.19.0 Nov 8, 2026
@pithead-developer
pithead-developer Bot changed the base branch from develop-v1.19.0 to develop November 8, 2026 19:32
@pithead-developer

Copy link
Copy Markdown
Contributor Author

develop-v1.19.0 was folded back into develop (#664, squash 5bf1bd8d) and this PR now targets develop. Rebasing its own 8 commit(s) with git rebase --onto origin/develop b1c25d6c0f74 astra/529-rigforge conflicts in: rigforge.sh . The branch was left unchanged at 49dc9fe5 for the worker to resolve; until then its diff against develop includes the old integration history.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stage/operator parked for the operator

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

0 participants