Skip to content

Add JSON doctor reports with stable check IDs - #606

Merged
pithead-reviewer[bot] merged 9 commits into
develop-v1.19.0from
astra/440-rigforge
Nov 8, 2026
Merged

pithead-reviewer[bot] merged 9 commits into
develop-v1.19.0from
astra/440-rigforge

Conversation

@pithead-developer

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

Copy link
Copy Markdown
Contributor

What's the problem

RigForge #440: automation must parse human prose to read worker health. Doctor has no machine report or stable check identifiers.

How I fixed it

Added doctor --json with {version, exit, summary, checks} on stdout and the existing human report on stderr. Every doctor finding has an explicit stable ID. The same probes and critical/advisory exit rules remain in use; a JSON encoding failure stops the doctor run, and the report it prints carries exit: 1 and the process exits 1, and temporary records are removed.

Updated help, completion, and operations documentation. Added isolated regression coverage and a tier4 contract assertion after the existing live connection/share wait. status --json is deferred, following the issue brief's default scope. The doctor dispatch keeps doctor_command "$@" || exit 1 so an unhealthy report exits 1 without firing the ERR trap's "aborted while" line.

Shortcut: critical findings are warn rows and only the top-level exit marks a report critical, so summary.fail is always 0 today; upgrade when a consumer needs to know which row is critical.

Here is the proof

Head 7b7eab67fb19ac15db5ce39f56748f9c59d26d78, base develop-v1.19.0, GitHub reports MERGEABLE. Since the last review, the head merged #645 (solo daemon pools), and #645's daemon-pool node-health rows in util/daemon-pools.sh had no ID, so a daemon-pool rig emitted "id":"". All three of those rows (synced ok, syncing warn, get_info unavailable warn) now carry pool-connection. That is the same row a Stratum pool reports, so automation reads one ID in every pool mode. docs/configuration.md now names the ID.

Regression red/green, bash tests/test-doctor-json.sh. The new cases run the real doctor via doctor_json: three with the running miner reporting a daemon connection (synced, syncing, down), and one with the service stopped, where the real _active_daemon_pool and get_info parsing run against a stubbed curl:

  • with util/daemon-pools.sh from e2a6ce4 (before the fix): exit 1, 47 passed, 4 failed. All four daemon cases fail, and their reports show {"id":"","status":"ok","message":"node connection live: height 123 (synced)"} and similar rows.
  • at this head: 51 passed, 0 failed.

Local on this head: make test-suite rc=0, run at 238a849; the follow-up commit only adds a test case to tests/test-doctor-json.sh. Also passing here: FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh, make lint-topology, and shellcheck --severity=warning plus shfmt -i 4 -d on the changed files. make lint stops at tests/run.sh, which is unchanged from the base, only because the local shfmt is 3.13.1 and CI pins 3.14.1.

GitHub checks at this head (gh pr checks 606): all 10 pass: Lint (shellcheck + shfmt), Lint (markdownlint), Lint (yamllint), Workflow audit (zizmor), Secret scan (gitleaks), Test suite, End-to-end (Docker), Coverage (kcov + diff-cover), Stock home setup (current), Stock home setup (historical).

Bench contract gate, tier4-e2e narrowed to phase connect, which runs e2e_doctor_json after the live share wait. The job rows show the five doctor JSON rows passing: one schema-valid report, exit matches process status, summary matches check rows, live service check, live pool connection check.

bench-ci job 3592@7b7eab67fb19ac15db5ce39f56748f9c59d26d78 · rigforge · tier4-e2e

  • options: {"phases": ["connect"]}
  • status: completed · conclusion: success · exit 0 · 2m 28s
  • 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: 8 pass · 0 fail · 0 skip
    Generated by bench-ci evidence 3592@7b7eab67fb19ac15db5ce39f56748f9c59d26d78; re-run it to check.

Not covered on the bench: the bench rig mines to the bench's Stratum stack, so the live gate never reaches the daemon-pool branch. That branch is covered by the unit cases above.

Ponytail review: nothing cut. The fix is three ID arguments plus one doc phrase, and the tests reuse the existing run_connected harness.

Closes #440

🤖 Generated with Claude Code

Part of #440. 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 stage/operator parked for the operator and removed operator-action Needs the operator's hands, not an answer: nothing waits on it and no ruling clears it labels Nov 2, 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:06
pithead-developer[bot] and others added 2 commits November 7, 2026 01:07
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@pithead-developer pithead-developer Bot added stage/in-progress and removed stage/blocked its issue waits on another issue labels Nov 7, 2026
…budget

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@pithead-reviewer

Copy link
Copy Markdown
Contributor

FAIL

What I investigated

I reviewed PR #606 at head c74a571 against issue #440, which asks for doctor --json with stable check IDs and the same contract as Pithead's. The code does what the issue asks, its tier-1 test fails without the fix and passes with it, and the GitHub checks are green. It is returned because the head has no bench-ci tier4-e2e job: the issue's evidence-tier ruling requires one, and the PR body says it is "still required". The PR also adds a source comment in an edited hunk.

  • gh pr view 606: head c74a571, base develop-v1.19.0 (same commit as origin/develop, b1c25d6). It touches rigforge.sh, util/doctor-report.sh, tests/e2e-pithead.sh, tests/e2e-doctor-json.sh, tests/test-doctor-json.sh, the Makefile, README.md and docs/operations.md.

  • Issue No machine-readable output on any verb: doctor and status are prose only #440 investigation brief (pithead-developer, 2026-09-24): 'evidence_tier: corrected ... to tier4-e2e required ... must scope a rigforge tier4-e2e job into the same PR'. status --json is deferred by default, and the PR body says it is deferred.

  • gh pr checks 606 --json: all 10 checks pass (Test suite, Coverage, End-to-end (Docker), shellcheck+shfmt, markdownlint, yamllint, gitleaks, zizmor, both stock-home setups). None were skipped.

  • bench-ci list --all --fleet --repo rigforge --commit c74a5716a14962b183fed371b3ba98d5af6d0078 printed 'queued 0, in progress 0, completed 0' and an empty table, so the head has no bench-ci job.

  • bash tests/test-doctor-json.sh at the head: rc=0, '46 passed, 0 failed'.

  • In a scratch worktree under $TMPDIR with rigforge.sh reset to origin/develop-v1.19.0 and util/doctor-report.sh removed, bash tests/test-doctor-json.sh: rc=1, '10 passed, 36 failed'. The test fails without the fix.

  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh: 'File budget OK'.

  • git diff -U0 origin/develop-v1.19.0...HEAD | grep '^+.*#': the only added explanatory comment is at rigforge.sh:6262. The other matches are shellcheck directives and code.

  • detect-topology.py on the PR body, the PR comments and the issue comments: all 'clean', rc=0.

  • tests/e2e-doctor-json.sh:39, util/doctor-report.sh:11-13: Nothing ever records fail: critical findings are warn rows, and only exit shows they are critical, as docs/operations.md says. So the e2e check .summary.fail == 0 can never fail, and a consumer cannot tell which warn row made exit non-zero. Pithead's contract has a fail status. This is not blocking because it is documented, but it is worth an issue if the dashboard needs to know which check is critical.

  • PR body, 'Here is the proof': The body's proof is all from a local run. It includes a local docker run, which is not evidence under this project's rules, and says no bench job was made. When the tier4 job is added, replace that with the bench-ci evidence block and the GitHub checks at the head.

Reviewed head: c74a5716a14962b183fed371b3ba98d5af6d0078.

What are the gaps

  • tests/e2e-pithead.sh:197 (e2e_doctor_json in phase_connect); bench-ci list --commit c74a571: The head has no bench-ci tier4-e2e job. The PR adds a new assertion to the worker-to-coordinator contract gate (e2e_doctor_json, which needs live service and pool-connection rows and a schema-valid report). The issue No machine-readable output on any verb: doctor and status are prose only #440 brief rules that this change needs a rigforge tier4-e2e job on the head. That assertion has never run on a rig, and the PR body says the job is 'Still required'. Submit a tier4-e2e job (targeted or matrix) on the head and paste its bench-ci evidence <id>@<sha> block, with the doctor JSON rows green, into the body.
  • rigforge.sh:6262: This edited hunk adds an explanatory source comment: ;; # ||: a mere unhealthy report must not fire the ERR trap's "aborted while" line. Moving it to the new ;; line also separates it from the || it describes. Delete the comment, and put the reason in docs or the PR body if it is needed.

@pithead-developer pithead-developer Bot added stage/needs-work returned by the reviewer, red CI, or conflicts with the base stage/in-review a reviewer session is on it now and removed stage/in-review a reviewer session is on it now stage/needs-work returned by the reviewer, red CI, or conflicts with the base labels Nov 7, 2026
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 and removed stage/in-review a reviewer session is on it now labels Nov 7, 2026
@pithead-developer pithead-developer Bot added stage/in-progress and removed stage/bench-testing its issue waits on a queued or running tier-4 bench job labels Nov 7, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

PASS

What I investigated

Round 3 re-review of #606 (doctor --json with stable check IDs, #440). The last reviewed head is c74a571, which is in this clone. Since then the worker made one commit of their own (90670b3, which drops the dispatch comment) and merged develop-v1.19.0 at a985c6e. Both round-2 return findings are closed at head da61abe. tier4-e2e job 3561 ran on this head and passed. Its log shows all five doctor JSON rows passing. The merge kept every SHARED_HOST guard from the base, and nothing in the head's rigforge/util/tests diff against the base adds a comment beyond shellcheck directives.

  • git cat-file -e c74a571: present. git log --no-merges c74a571..da61abe: the worker's only commit is 90670b3. The rest (39526ae, 65f4587, cbca1a0, a985c6e) came in through the base merge.
  • Round 2 return, rigforge.sh:6262 comment: FIXED. git show 90670b3 changes ;; # ||: a mere unhealthy report ... to ;;.
  • Round 2 return, missing tier4-e2e: FIXED. bench-ci evidence 3561@da61abed650b58df7d7ccc3523feaea8d3ec647d exit 0 prints: tier4-e2e, options {"phases": ["connect"]}, completed, conclusion success, exit 0, baseline verified yes, rig restored yes, every step success, rows 8 pass 0 fail 0 skip. This is byte-identical to the block in the PR body.
  • bench-ci log 3561 (49 lines): line 1 rigforge@da61abed..., line 22 checks out da61abe on the rig. Lines 28-32 show ✓ for each doctor JSON row: one schema-valid report, reported exit matches process status, summary matches check rows, service check is live, pool connection check is live. Line 36: phase connect: passed (8 assertions, 0 skipped).
  • Round 2 note, summary.fail is always 0: answered. The body's How I fixed it section records it as a shortcut with an upgrade trigger. It stays a note and does not block.
  • Round 2 note, local-only proof: answered. The body now quotes bench-ci jobs 3561 (head) and 3511 (pre-merge head) and the GitHub checks at the head.
  • gh pr checks 606 --json: all 10 pass at the head, none skipped (Lint shellcheck+shfmt, markdownlint, yamllint, zizmor, gitleaks, Test suite, End-to-end Docker, Coverage kcov, Stock home setup current and historical).
  • Merge resolution: grep -c SHARED_HOST in rigforge.sh is 26 at a985c6e and 26 at da61abe. git diff a985c6e da61abe -- rigforge.sh | grep -c '^-.*SHARED_HOST' gives 0.
  • git diff a985c6e da61abe -- rigforge.sh util/ tests/ Makefile: the only added # lines are # shellcheck source=util/doctor-report.sh and # shellcheck disable=.... These are functional directives.
  • bash tests/test-doctor-json.sh at the head: 46 passed, 0 failed, exit 0. bash tests/test-shared-host.sh: exit 0.
  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh: exit 0, 'file budget OK'.
  • detect-topology.py over the PR body, the PR comments and the No machine-readable output on any verb: doctor and status are prose only #440 comments printed clean, exit 0.

Reviewed head: da61abed650b58df7d7ccc3523feaea8d3ec647d.

@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 7, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

Owner brief for da61abed650b

What it does. rigforge doctor --json now prints one JSON report on stdout: version, exit status, a count summary, and a list of checks. Each check has a stable ID, a status and a message. The human-readable report moves to stderr, and the same checks and exit rules apply. Plain doctor is unchanged. Help, bash completion, the README and the operations guide are updated.

Why. Closes #440 (milestone v2.x post-GA). Automation had to parse the doctor's prose to read worker health, and that wording can change between releases. The issue asks for the same shape as Pithead's doctor --json, with stable check IDs from the start. status --json is deferred, which the issue allows ("if it is cheap").

Risk. Low. The change is additive: plain doctor behaves as before, and --json is a new flag. The one existing path touched is the doctor dispatch in rigforge.sh, which now passes arguments through and exits 1 on an unhealthy report. The check-ID edits in rigforge.sh are mechanical (an extra argument on each _ck_* call). Nothing is irreversible. One limit: critical findings are warn rows and summary.fail is always 0, so consumers must read the top-level exit.

Proof. CI: 11 success. Reviewer: PASS at da61abe by pithead-reviewer, round 2 (recorded 2026-11-07T19:50:00Z). Bench: job 3561: success on the head; job 3511: success on 90670b3, not the head.

What to check.

  • util/doctor-report.sh:19-33: doctor_json runs doctor, collects the rows through a temp file, and passes doctor's exit code through. A JSON encoding failure at line 8 exits 1, and the EXIT trap removes the temp file.
  • rigforge.sh:6242-6245 and the validation case at rigforge.sh:6213: doctor leaves the no-extra-argument list and gets its own dispatch. Confirm doctor_command "$@" || exit 1 keeps the old exit behavior.
  • rigforge.sh:5518-5532 and the nearby SHARED_HOST guards: the merge kept the base's guards and added IDs on every _ck_* call. Check that no check lacks an ID, since an empty ID would produce a blank-ID row.
  • docs/operations.md:94-118: the contract says exit is the health authority, fail is reserved at 0, and IDs such as socks-proxy can repeat. Decide whether you accept that limit.

Verdict. merge

VijitSingh97
VijitSingh97 previously approved these changes Nov 8, 2026
@pithead-developer pithead-developer Bot added stage/needs-check stage/in-review a reviewer session is on it now and removed stage/awaiting-merge the reviewer's PASS is on the head; merging when checks and the base allow stage/needs-check labels Nov 8, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

FAIL

What I investigated

Re-review of the diff from c74a571 to the head e2a6ce4. The worker's only commit in that range is 90670b3, which deletes the dispatch comment. The rest arrived in two base merges: a985c6e is in da61abe, and #645 (solo daemon pools) is in e2a6ce4. Both round-2 return findings are now closed. The head still fails because the latest merge breaks the PR's main claim: on a solo daemon-pool rig, doctor --json writes check rows with an empty id. The PR's own e2e gate rejects that report as invalid, and no test or bench job covers the case.

  • git cat-file -e c74a571 worked, so the old head is in this clone. git log --no-merges c74a571..e2a6ce4 lists 90670b3 (the worker's commit) plus base commits Add an opt-in shared-host resource profile #611, Automate docs replay, API allowlist, and uninstall checks #617, Expose appliance mode and baked ref in the sister feed #637, Qualify historical RigForge benchmark claims #639 and Support solo daemon pools and report node health #645.
  • Earlier finding rigforge.sh:6262 (added comment): fixed. git show 90670b3 changes the line to a bare ;;.
  • Earlier finding 'no tier4-e2e job': answered for the head it tested. bench-ci evidence 3561@da61abed… prints the same block as the PR body: success, exit 0, rows 8 pass, 0 fail. Lines 28-32 of bench-ci log 3561 show all five doctor JSON rows passing, and line 22 shows it checked out da61abe. bench-ci evidence 3511@90670b3… also matches the body. bench-ci list --commit e2a6ce44… shows 0 jobs. The diff da61abe..e2a6ce4 changes the doctor code in rigforge.sh (_doctor_daemon_status calls at rigforge.sh:5471 and :5486), so neither job covers the head.
  • Earlier note (summary.fail always 0): the body now states it under 'How I fixed it' as a known limit. It stays a note.
  • Earlier note (proof was local-only): fixed. The body now quotes bench-ci evidence and the GitHub checks.
  • The PR's own diff is unchanged by the merge. Comparing the +/- lines of git diff a985c6e da61abe with those of git diff 4ae7fb8 e2a6ce4 gives no difference. git diff --stat 4ae7fb8 e2a6ce4 lists 8 files, 467 insertions and 82 deletions.
  • Searching rigforge.sh and util/*.sh for _ck_* calls with no ID argument finds util/daemon-pools.sh:88, :90 and :94, which doctor reaches. It also finds rigforge.sh:5971 and :6063, but those are in _bios_guide and _bios_verify, outside doctor.
  • Repro: sourcing util/doctor-report.sh and util/daemon-pools.sh with _DR_JSON_FILE set and calling _doctor_daemon_status writes {"id":"","status":"ok","message":"node connection live: height 123 (synced)"} and {"id":"","status":"warn",...}.
  • bash tests/test-doctor-json.sh passes (46 passed, 0 failed) and bash tests/test-daemon-pools.sh passes (141 passed, 0 failed). Neither one runs doctor --json against a daemon pool.
  • gh pr checks 606 --json at the head shows all 10 checks SUCCESS and none skipped.
  • FILE_BUDGET_REQUIRE_BASE=1 bash scripts/lint-file-budget.sh printed 'File budget OK' and exited 0.
  • detect-topology.py run over the PR body, PR comments and issue No machine-readable output on any verb: doctor and status are prose only #440 comments printed clean. The only comment authors are pithead-developer and pithead-reviewer.

Reviewed head: e2a6ce44b9dffcd335bd5d293fba0428aeb90096.

What are the gaps

  • util/daemon-pools.sh:88,90,94 (called from doctor at rigforge.sh:5471 and rigforge.sh:5486): After the Support solo daemon pools and report node health #645 merge, doctor on a solo daemon-pool rig writes the pool and node health rows through _ck_ok and _ck_warn with no ID. doctor --json therefore emits "id":"". Repro: source util/doctor-report.sh and util/daemon-pools.sh, set _DR_JSON_FILE, and call _doctor_daemon_status "$(printf 'daemon\tx\t123\tsynced')". It records {"id":"","status":"ok",...}. This contradicts the body's claim that every doctor finding has an explicit stable ID. Automation also gets no stable row for pool or node health on a supported pool mode, which is what No machine-readable output on any verb: doctor and status are prose only #440 asks for. tests/e2e-doctor-json.sh:17 requires a non-empty .id, so the gate's 'one schema-valid report' row would fail on such a rig. At the da61abe merge you added IDs to the base's new _ck_* calls; this merge needs the same. Give these three calls a stable ID: reuse pool-connection, or add a documented node-connection. Add it to docs/operations.md if the IDs are listed there. Add a tests/test-doctor-json.sh case that runs the daemon path and asserts the ID. Show that case red before the fix and green after it.
  • bench-ci list --commit e2a6ce4: The head has no tier4-e2e job, and the merge since job 3561 changed the doctor code. After the fix above, run a tier4-e2e job (connect phase as before) on the new head. Replace the body's head SHA (it still says da61abe) and its evidence block with that job's bench-ci evidence <id>@<sha> block.

@pithead-developer pithead-developer Bot added stage/in-progress and removed stage/in-review a reviewer session is on it now labels Nov 8, 2026
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 8, 2026
@pithead-reviewer

Copy link
Copy Markdown
Contributor

PASS

What I investigated

Round-3 re-review of rigforge#606 at head 7b7eab6, covering the two worker commits since e2a6ce4 (that commit is in this clone). Every earlier return finding is fixed. All three daemon-pool doctor rows now carry pool-connection; the new cases fail with the fix reverted (47 pass/4 fail) and pass at head (51/0); bench-ci job 3592 ran tier4-e2e on this exact head with all five doctor JSON rows green; all 10 GitHub checks pass, and the local make test-suite passes at head.

  • git cat-file -e e2a6ce4… passed. git log --no-merges e2a6ce4..7b7eab6 lists 238a849 and 7b7eab6, the worker's own commits. Diff: docs/configuration.md +2/-1, tests/test-doctor-json.sh +17/-5, util/daemon-pools.sh +3/-3.

  • Earlier finding util/daemon-pools.sh:88,90,94 (ID-less rows): FIXED. At head, lines 88, 90 and 94 pass pool-connection as the ID argument to _ck_ok/_ck_warn. A grep for ID-less _ck_* calls finds them only in _bios_guide (rigforge.sh:5966) and _bios_verify (rigforge.sh:6020). Both are called only from bios() (rigforge.sh:6101), never from doctor() (rigforge.sh:5414).

  • Red/green: in a scratch copy of the head made with git archive, with util/daemon-pools.sh restored from e2a6ce4, bash tests/test-doctor-json.sh exits 1 with 47 passed, 4 failed. The four failures are the synced, syncing, unavailable and stopped-service daemon cases, each failing the all(.checks[]; .id != "") filter. At head: rc=0, 51 passed, 0 failed. The test is registered at Makefile:19.

  • Earlier finding rigforge.sh:6262 (added explanatory comment): FIXED. git diff 4ae7fb8..HEAD (merge-base with develop-v1.19.0) adds no # comment lines except shebangs and # shellcheck directives. The dispatch at rigforge.sh:6235 is plain doctor_command "$@" || exit 1.

  • Earlier findings on the missing tier4-e2e job at c74a571 and at e2a6ce4: FIXED. bench-ci evidence 3592@7b7eab67fb19ac15db5ce39f56748f9c59d26d78 printed a block identical to the PR body's: tier4-e2e, phases [connect], completed, success, exit 0, 8 pass · 0 fail · 0 skip, baseline verified, rig restored. bench-ci status 3592 --json shows commit 7b7eab6 and five passing rows: 'doctor JSON: one schema-valid report', 'reported exit matches process status', 'summary matches check rows', 'service check is live', 'pool connection check is live'. The job log reads 'phase connect: passed (8 assertions, 0 skipped)'.

  • Earlier note on local-only proof in the body: FIXED. The body now quotes the head SHA, the bench-ci evidence block and the GitHub checks.

  • Earlier note on summary.fail never being recorded: STANDS AS A NOTE. The body states it under 'How I fixed it' as a known limit.

  • gh pr checks 606 --json at head: all 10 checks pass (Lint shellcheck+shfmt, markdownlint, yamllint, zizmor, gitleaks, Test suite, End-to-end (Docker), Coverage (kcov + diff-cover), Stock home setup current and historical). None skipped.

  • make test-suite at head: suite_rc=0.

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

  • make test: rc=2 at make lint. The only shfmt diff is tests/run.sh, which the PR leaves unchanged (git diff --quiet 4ae7fb8 HEAD -- tests/run.sh). Local shfmt is 3.13.1 and CI pins a newer one; CI's pinned Lint check passes at head.

  • detect-topology.py over the PR body, all 8 PR comments and issue No machine-readable output on any verb: doctor and status are prose only #440's body and comments: printed 'clean', rc=0.

  • Diff review: the 3 ID arguments fix the root cause in shared code. The doc sentence is corrected in place, not appended. The run_connected harness gained positional name, pool-status and config arguments plus STUB_SERVICE_ACTIVE/STUB_CURL_BODY stubs, with defaults that keep the existing cases unchanged. No relaxed or deleted tests, no added comments, no over-engineering worth a note.

  • util/doctor-report.sh:11-13; tests/e2e-doctor-json.sh:39: Carried from round 2, not blocking. No code path records fail: critical findings are warn rows, and only .exit marks a report critical, so .summary.fail == 0 can never fail. The body states this limit. Open an issue if the Pithead dashboard needs to know which row is critical.

  • PR body, 'Here is the proof': The body says it ran make test-suite at 238a849. It also passes at the head (suite_rc=0), so update the body to name the head.

Reviewed head: 7b7eab67fb19ac15db5ce39f56748f9c59d26d78.

@pithead-reviewer

Copy link
Copy Markdown
Contributor

Owner brief for 7b7eab67fb19

What it does. Adds doctor --json to RigForge. It prints one JSON report to stdout with version, exit, summary and checks, and the usual human report goes to stderr. Every doctor finding now carries a stable ID such as service, hugepages or pool-connection. Plain doctor behaves as before. Help, bash completion and the docs are updated.

Why. Closes #440 (milestone v2.x post-GA). Before this, automation and the Pithead dashboard had to parse doctor's prose to read a rig's health, and that wording can change between releases. status --json is not included, which the PR says matches the issue's default scope.

Risk. Low. The probes and exit rules are unchanged, and the only new path is the --json flag. The doctor dispatch moves into a new doctor_command wrapper, and the extra-argument check for doctor moved with it. summary.fail is always 0 today, so consumers must use the top-level exit to tell whether a report is critical. The docs say so. Nothing is irreversible.

Proof. CI: 11 success. Reviewer: PASS at 7b7eab6 by pithead-reviewer, round 3 (recorded 2026-11-08T03:56:13Z). Bench: job 3592: success on the head.

What to check.

  • util/doctor-report.sh:7-17: the _ck_* helpers now write each row to a temp file and abort (exit 1) if encoding fails. Check that this exit inside the doctor subshell gives the stated behaviour: report carries exit: 1 and temp files are removed.
  • rigforge.sh:6233-6236: the dispatch doctor_command "$@" || exit 1, and the removal of doctor from the no-extra-args list at about line 6204. Confirm doctor extra still errors.
  • util/daemon-pools.sh:88-94: the three daemon-pool rows now use pool-connection, the same ID as Stratum pools. The bench never reaches this branch, so only the unit cases cover it (tests/test-doctor-json.sh daemon-* cases).
  • docs/operations.md:94-118: the documented contract, including that IDs may repeat (for example socks-proxy) and that messages are not stable.

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 8, 2026
@pithead-reviewer
pithead-reviewer Bot merged commit eb50ae2 into develop-v1.19.0 Nov 8, 2026
11 checks passed
@pithead-reviewer
pithead-reviewer Bot deleted the astra/440-rigforge branch November 8, 2026 05:47
pithead-developer Bot pushed a commit that referenced this pull request Nov 8, 2026
The base grew solo daemon pools (#645), the source-drift apply-state
check (#609) and JSON doctor reports (#606) after the first sync, which
the bench caught as a conflict with the tested head. Resolutions: keep
the xmrig overlay alongside the new daemon-pools source and pool keys;
keep the overlay doctor line next to the new apply-state check; keep
the broadened util/ coverage denominator over the individually named
helpers. tests/test-config-apply-state.sh gains a validator stub in its
fixture because apply now requires a validation executable; its
assertions are unchanged.

Co-Authored-By: Claude Code <noreply@anthropic.com>
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.

No machine-readable output on any verb: doctor and status are prose only

1 participant