feat(FN-4278): clarify orphaned-running timeout semantics in agent heartbea

Clarifies orphaned-running timeout semantics in the agents documentation and adds a related implementation detail in the agent heartbeat module.

Fusion-Task-Id: FN-4278
This commit is contained in:
Fusion
2026-05-13 08:14:46 -07:00
committed by gsxdsm
parent 7f86215a9e
commit 0683611ea3
2 changed files with 16 additions and 7 deletions

View File

@@ -892,6 +892,13 @@ export class HeartbeatMonitor {
} else if (!this.trackedAgents.has(agent.id)) {
const timeoutMs = this.resolveAgentConfig(agent.id).heartbeatTimeoutMs;
const heartbeatAgeMs = getHeartbeatAgeMs(agent, now);
// NOTE(FN-4278): this stale gate intentionally uses a per-run work-budget
// multiplier (`heartbeatTimeoutMs × 3`) because this path is only for
// untracked persisted `state="running"` rows where an in-memory tracked
// session is absent. It is not the direct-report freshness classifier.
// Freshness/staleness for active+idle reports is interval-based in
// `buildReportsHealthSection()` and dashboard `agentHealth.tsx` via
// `max(heartbeatIntervalMs × 4, 5m)` (FN-4255).
if (!Number.isFinite(heartbeatAgeMs) || heartbeatAgeMs > timeoutMs * 3) {
try {
await terminatePersistedHeartbeatRun(