fix(await-signal): update agent last_activity on signal received (#774)

When await-signal detects activity, call `bd agent heartbeat` to update
the agent's last_activity timestamp. This enables witnesses to accurately
detect agent liveness and prevents false "agent unresponsive" alerts.

Previously, await-signal only managed the idle:N label but never updated
last_activity, causing it to remain NULL for all agents.

Fixes #773
This commit is contained in:
Daniel Sauer
2026-01-20 23:10:26 +01:00
committed by GitHub
parent 5c45b4438a
commit 6a22b47ef6

View File

@@ -160,7 +160,14 @@ func runMoleculeAwaitSignal(cmd *cobra.Command, args []string) error {
result.IdleCycles = newIdleCycles
}
} else if result.Reason == "signal" && awaitSignalAgentBead != "" {
// On signal, report current idle cycles (caller should reset)
// On signal, update last_activity to prove agent is alive
if err := updateAgentHeartbeat(awaitSignalAgentBead, beadsDir); err != nil {
if !awaitSignalQuiet {
fmt.Printf("%s Failed to update agent heartbeat: %v\n",
style.Dim.Render("⚠"), err)
}
}
// Report current idle cycles (caller should reset)
result.IdleCycles = idleCycles
}
@@ -319,6 +326,14 @@ func parseIntSimple(s string) (int, error) {
return n, nil
}
// updateAgentHeartbeat updates the last_activity timestamp on an agent bead.
// This proves the agent is alive and processing signals.
func updateAgentHeartbeat(agentBead, beadsDir string) error {
cmd := exec.Command("bd", "agent", "heartbeat", agentBead)
cmd.Env = append(os.Environ(), "BEADS_DIR="+beadsDir)
return cmd.Run()
}
// setAgentIdleCycles sets the idle:N label on an agent bead.
// Uses read-modify-write pattern to update only the idle label.
func setAgentIdleCycles(agentBead, beadsDir string, cycles int) error {