Repository navigation
feat(fleet): live health indicators with staleness detection (#1375) - #1389
Merged
jeonghun-jj-lee merged 6 commits intoSep 21, 2026
Merged
Conversation
…uildFleetSectionModel (#1375) Layer 1: effectiveHealth pure function with DEGRADED_AGE_MS (180s) and DOWN_AGE_MS (300s) staleness thresholds. formatAge helper for tooltips. Layer 2: buildFleetSectionModel now accepts an injectable clock (now?), maps roster rows through effectiveHealth, carries rosterHealth (raw) and now through to the model. Self-row and canonical-server are EXEMPT. Existing tests preserved via pinned clock in test input() helper.
…1375) Layer 3: deviceTooltip now shows relative age (formatAge) instead of raw ISO timestamps when now is available, and annotates staleness-derived health changes with 'degraded (no heartbeat)' / 'down (no heartbeat)'. renderDeviceRow passes model.now through.
Layer 4: 60s setInterval in resolveWebviewView re-pushes fleet status so display health transitions (reachable → degraded → down) even when the roster file is static. Cleaned up in onDidDispose.
Layer 5: FleetHeartbeat periodically POSTs this machine's own roster row with health: 'reachable' and a fresh last_report to POST /amicode/roster. Full DI seams for testability. Guards: no-op when resolveIdentity returns null. Errors swallowed silently (next tick is the retry).
…tures (#1375) Layer 6: FleetHeartbeat started after sidebar setup in activate(), with lazy service endpoint resolution. Disposed in deactivate() and via ctx.subscriptions. Also fixes sidebar_view.test.ts test fixtures: deviceRow helper now uses Date.now() for last_report so effectiveHealth staleness doesn't falsely degrade reachable rows in the test harness.
- lint-skills-known.txt: add create-a-fleet companion exemption for tools/fleet/README.md (a repo-root cross-reference, same pattern as the other known entries) - amicode_service_runner.test.ts: use a stub engine binary for the 'no app dist' test so it doesn't depend on the gitignored vendored binary (absent in worktrees and CI without a build step)
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
jeonghun-jj-lee
added a commit
that referenced
this pull request
Sep 23, 2026
…1389) * feat(fleet): effectiveHealth + formatAge + staleness integration in buildFleetSectionModel (#1375) Layer 1: effectiveHealth pure function with DEGRADED_AGE_MS (180s) and DOWN_AGE_MS (300s) staleness thresholds. formatAge helper for tooltips. Layer 2: buildFleetSectionModel now accepts an injectable clock (now?), maps roster rows through effectiveHealth, carries rosterHealth (raw) and now through to the model. Self-row and canonical-server are EXEMPT. Existing tests preserved via pinned clock in test input() helper. * feat(fleet): enhanced tooltip with formatAge + staleness annotation (#1375) Layer 3: deviceTooltip now shows relative age (formatAge) instead of raw ISO timestamps when now is available, and annotates staleness-derived health changes with 'degraded (no heartbeat)' / 'down (no heartbeat)'. renderDeviceRow passes model.now through. * feat(fleet): staleness sweep timer in sidebar view (#1375) Layer 4: 60s setInterval in resolveWebviewView re-pushes fleet status so display health transitions (reachable → degraded → down) even when the roster file is static. Cleaned up in onDidDispose. * feat(fleet): FleetHeartbeat class — periodic roster self-report (#1375) Layer 5: FleetHeartbeat periodically POSTs this machine's own roster row with health: 'reachable' and a fresh last_report to POST /amicode/roster. Full DI seams for testability. Guards: no-op when resolveIdentity returns null. Errors swallowed silently (next tick is the retry). * feat(fleet): wire FleetHeartbeat in extension.ts + fix stale test fixtures (#1375) Layer 6: FleetHeartbeat started after sidebar setup in activate(), with lazy service endpoint resolution. Disposed in deactivate() and via ctx.subscriptions. Also fixes sidebar_view.test.ts test fixtures: deviceRow helper now uses Date.now() for last_report so effectiveHealth staleness doesn't falsely degrade reachable rows in the test harness. * fix(test): resolve pre-existing test failures in worktree builds (#1375) - lint-skills-known.txt: add create-a-fleet companion exemption for tools/fleet/README.md (a repo-root cross-reference, same pattern as the other known entries) - amicode_service_runner.test.ts: use a stub engine binary for the 'no app dist' test so it doesn't depend on the gitignored vendored binary (absent in worktrees and CI without a build step)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fleet sidebar connection indicators are now live and robust — peer dots reflect real-time reachability, not frozen enrollment-time health.
What changed
Two-layer heartbeat + staleness detection:
FleetHeartbeatclass (fleet_heartbeat.ts) — each machine periodically re-POSTs its own roster row with a freshlast_reporttimestamp (60s interval). Single-writer invariant preserved: each machine only writes its own row.effectiveHealth()(sidebar_fleet_section.ts) — computes display health fromlast_reportage:< 3 min→ green (reachable)3–5 min→ yellow (degraded)> 5 min→ red (down)degraded/down) are never overridden by staleness.Staleness sweep — 60s
setIntervalin sidebar view callspushFleetStatus()so dots transition even whenroster.jsonis static.Enhanced tooltips — dot and row tooltips show relative age + staleness annotation when display health differs from roster health.
Tests
28 new tests across 3 files covering:
effectiveHealthboundary conditions (all threshold transitions)formatAgeoutput formattingAlso fixes 2 pre-existing test failures:
skills_integrity: addedcreate-a-fleet/SKILL.md:companionto known-listamicode_service_runner: replaced gitignoredENGINE_BINwith stub executableFull suite green: 260 files, 4136 tests passed, 0 failed.
Closes #1375