Skip to content

fix: an unreachable machine is not a machine earning nothing (beads batch 8) - #190

Merged
GeiserX merged 2 commits into
mainfrom
fix/beads-batch-8
Aug 4, 2026
Merged

fix: an unreachable machine is not a machine earning nothing (beads batch 8)#190
GeiserX merged 2 commits into
mainfrom
fix/beads-batch-8

Conversation

@GeiserX

@GeiserX GeiserX commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Two findings, one mistake: both endpoints are built only from online workers, and both then presented the resulting absence as measured fact.

daq — an offline worker was told to switch itself off.

per_worker_gross comes from online workers only, and the endpoint defaulted a missing entry to 0.0. So a host that had merely stopped heartbeating produced a confident financial recommendation:

geiserback earns about 0.00 a month and costs about 9.49 in electricity — roughly 9.49 out of pocket. Since this machine runs only these services, turning it off would save that.

Its earnings were also silently reattributed to whatever workers were still reporting, so the rest of the fleet looked better than it was at the same moment.

assess_machine now takes monthly_gross | None and returns UNKNOWN with no cost, net or gross. A machine that genuinely earned 0.00 is still judged — asserted, because a fix that stopped judging anything would pass the other tests.

1qy — an unreachable worker read as "you have no services".

Three minutes after a host stops heartbeating, the table emptied and the dashboard stated as fact that the user had nothing and should start over — with a Setup Wizard button. The containers were still running and still earning.

The empty state now asks /api/workers before choosing its sentence, says containers keep running and earning while a worker is offline, and when it cannot reach that endpoint either, asserts neither case rather than guessing. A genuinely empty install still gets the wizard.

Verification: 2493 tests, 95.13% coverage, ruff clean, JS parses. Negative controls: removing the unknown-gross branch fails 3 tests; collapsing the empty-state condition fails 1.

Batch 8. Two findings, one mistake: both endpoints are built only from
ONLINE workers, and both then presented the resulting absence as a
measured fact.

CashPilot-daq — an offline worker was told to switch itself off.
  per_worker_gross is built from online workers only, and the endpoint
  defaulted a missing entry to 0.0, so a host that had merely stopped
  heartbeating produced a confident financial recommendation:
  "geiserback earns about 0.00 a month and costs about 9.49 in
  electricity — roughly 9.49 out of pocket. Since this machine runs only
  these services, turning it off would save that."

  Its earnings were also being silently reattributed to whatever workers
  were still reporting, so the rest of the fleet looked better than it
  was at the same moment.

  assess_machine now takes monthly_gross | None and returns UNKNOWN with
  no cost, no net and no gross when it is None. A machine that genuinely
  earned 0.00 is still judged — asserted, because a fix that stopped
  judging anything would pass the other tests.

CashPilot-1qy — an unreachable worker read as "you have no services".
  Three minutes after a host stops heartbeating — a reboot, a network
  blip, a worker container restart — the table emptied and the dashboard
  stated as fact that the user had nothing and should start over, with a
  Setup Wizard button. The containers were still running and still
  earning.

  The empty state now asks /api/workers before deciding which sentence
  to show, says the containers keep running and earning while a worker
  is offline, and — when it cannot even reach that endpoint — asserts
  neither case rather than guessing. A genuinely empty install still
  gets the wizard.

Negative controls: removing the unknown-gross branch fails three tests,
collapsing the empty-state condition fails one.
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@GeiserX, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 55ba679d-38ec-48ce-8a0d-e15baacc2778

📥 Commits

Reviewing files that changed from the base of the PR and between 82cc414 and d9e4e9f.

📒 Files selected for processing (4)
  • app/machine_economics.py
  • app/main.py
  • app/static/js/app.js
  • tests/test_beads_batch_8.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.08%. Comparing base (82cc414) to head (d9e4e9f).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #190   +/-   ##
=======================================
  Coverage   95.08%   95.08%           
=======================================
  Files          46       46           
  Lines        5880     5883    +3     
=======================================
+ Hits         5591     5594    +3     
  Misses        289      289           
Files with missing lines Coverage Δ
app/machine_economics.py 100.00% <100.00%> (ø)
app/main.py 97.32% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Found in my own fresh review of this PR, not by an audit agent.

Making an unreachable machine report monthly_gross: None fixed the
per-machine verdict but pushed the same mistake up one level. The fleet
total sums that None as 0.0, so the headline gross silently shrinks by
whatever the unreachable machine earns, with nothing saying so — a
number that quietly gets smaller and looks like a real decline.

fleet_summary already guards exactly this for cost, and its docstring
says so: 'so the total never quietly understates what the fleet costs'.
The guard had simply never been extended to gross, because until this PR
gross was never unknown. It now counts unreadable machines and says so
in the summary.

Also asserted that fleet.html can render a null gross. Its money() helper
already returns an em dash for null, but monthly_gross only became
nullable in this PR, so a later simplification of that helper could turn
it into '0.00' or NaN without any test objecting.
@GeiserX

GeiserX commented Aug 4, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@GeiserX
GeiserX merged commit b812a20 into main Aug 4, 2026
6 checks passed
@GeiserX
GeiserX deleted the fix/beads-batch-8 branch August 4, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant