Skip to content

Redundant heartbeat mechanisms: systemd timer vs bridge.py heartbeat_loop #225

@nlenepveu

Description

@nlenepveu

Context

There are currently two separate heartbeat mechanisms that both send messages to the conductor session every N minutes:

1. heartbeat.sh (systemd timer / launchd plist)

  • Installed by conductor setup unconditionally (unless --no-heartbeat)
  • Sends a generic message asking Claude to check sessions:
    "Heartbeat: Check all sessions in the default profile. List any waiting sessions, auto-respond where safe, and report what needs my attention."
  • Claude has to call brigade status itself and do the work

2. heartbeat_loop() in bridge.py (async loop)

  • Runs inside the bridge process, installed only when Telegram or Slack is configured
  • Calls agent-deck brigade status --json, formats a summary, and sends it:
    "[HEARTBEAT] [ai-platform] Status: 6 waiting, 0 running, 3 idle, 1 error. Waiting sessions: ..."
  • Claude receives a pre-formatted summary and just needs to react

The install logic in conductor_cmd.go

conductor setup runs both steps independently:

  • Step 6: InstallHeartbeatScript() + InstallHeartbeatDaemon() — always (if heartbeat enabled)
  • Step 7: InstallBridgeScript() + InstallBridgeDaemon() — only if Telegram/Slack configured

There is no check to skip the systemd heartbeat timer when the bridge is also being installed.

Result

When Telegram or Slack is configured (which is the common case for conductor users), the conductor receives two heartbeat messages every interval — one asking it to check, and one giving it the answer. This doubles token usage for essentially the same purpose.

Suggestion

The systemd/launchd heartbeat timer makes sense as a fallback for setups without Telegram/Slack (no bridge running). But when the bridge is active, its heartbeat_loop already covers the same need more efficiently (pre-computes the summary, saves tokens).

Would you be open to a PR that makes the systemd heartbeat timer conditional — skip installation when the bridge is also being installed?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions