Skip to content

fix: an unreachable host reported its containers as running - #201

Merged
GeiserX merged 1 commit into
mainfrom
fix/beads-batch-18
Aug 4, 2026
Merged

fix: an unreachable host reported its containers as running#201
GeiserX merged 1 commit into
mainfrom
fix/beads-batch-18

Conversation

@GeiserX

@GeiserX GeiserX commented Aug 4, 2026

Copy link
Copy Markdown
Owner

The defect

The Fleet page coloured every container chip from the status frozen into the last heartbeat, with no staleness input:

const isRunning = status === 'running';
const color = isRunning ? 'var(--success)' : 'var(--text-muted)';

So a host that is powered off rendered a row of success-green chips — "honeygain, traffmonetizer" — next to a machine CashPilot had not heard from in hours. The only counter-signal was a grey dot and a "Last seen" line elsewhere on the card, and green is the louder signal.

renderApps had the same defect one function above. The bead named only the containers.

The fix

A colour is a claim about right now, and it can only be made while the worker is reachable.

The state is still shown — "what was running when we last heard" is genuinely useful — but as a memory rather than a measurement: muted, dashed, headed "Last known state — not reachable", with a tooltip naming when it was last true.

Evidence

Proof is a node harness, not a Python assertion, because these renderers live in a <script> block inside a Jinja template — a text assertion could only show the source mentions a variable, never what colour a given worker actually produces. The harness extracts the real functions and inspects their output (11 assertions).

CI runs it as its own step, and pytest shells out to it so a local run catches it too. A test also asserts CI invokes every browser-free harness, so a new one can't sit unrun.

Negative control:

reverted result
containers coloured from the frozen status ✗ "a powered-off host still reports its containers as running"
apps coloured from the frozen status ✗ "an unreachable phone still reports its apps as running"
hide the list entirely instead of marking it (the lazy fix) ✗ "nothing on the card says the state is not current"

The third matters: the obvious shortcut — just don't render the chips — fails a different assertion, so it can't pass by accident.

Controls also pin the ordinary cases: a reachable host still goes green, an exited container on a live host still reads stopped, and the app traffic tooltip survives alongside the new staleness one.

Closes CashPilot-1m8

The Fleet page coloured every container chip from the status frozen into the
worker's last heartbeat, with no staleness input. A host that is powered off
rendered a row of success-green chips — "honeygain, traffmonetizer" — next to a
machine CashPilot had not heard from in hours. The only counter-signal was a
grey dot and a "Last seen" line elsewhere on the card, and green is the louder
signal. renderApps had the same defect one function above; the bead named only
the containers.

A colour is a claim about right now, and that claim can only be made while the
worker is reachable. The state is still shown, because "what was running when
we last heard" is genuinely useful — it is now shown as a memory rather than a
measurement: muted, dashed, headed "Last known state — not reachable", with a
tooltip naming when it was last true.

Proof is a node harness rather than a Python assertion, because these renderers
live in a <script> block inside a Jinja template: a text assertion could only
show the source mentions a variable, never what colour a given worker produces.
The harness extracts the real functions and inspects their output. CI runs it as
its own step, and pytest shells out to it so a local run catches it too.

Negative control: colouring containers from the frozen status again fails it;
the same for apps; and hiding the list instead of marking it fails a different
assertion, so the lazy fix cannot pass either.

Closes CashPilot-1m8
@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: 24 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: 5ca53d0c-1393-4860-afc7-c48504351934

📥 Commits

Reviewing files that changed from the base of the PR and between 52b6ad6 and 077ec33.

📒 Files selected for processing (4)
  • .github/workflows/test.yml
  • app/templates/fleet.html
  • scripts/fleet_staleness_check.mjs
  • tests/test_javascript_is_parsed.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.

@GeiserX
GeiserX merged commit b340216 into main Aug 4, 2026
8 checks passed
@GeiserX
GeiserX deleted the fix/beads-batch-18 branch August 4, 2026 15:06
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