CB-551: idle-lead heartbeat — nudge an idle lead back to work on a timer #26

Closed
agent wants to merge 0 commits from worker/cb-551-idle-lead-heartbeat-f1633c-1 into main
Member

CB-551 — idle-lead heartbeat

An opt-in heartbeat that nudges the single idle lead back to work once it has been continuously idle past a quiet period with no open bridge_send driving it. Mirrors the ReplyPushLoop pattern (pure unit-testable decide() + thin scheduler) with a different trigger.

Design constraints honored:

  1. OPT-IN — absent leadHeartbeat: config block ⇒ loop never constructed, feature fully off.
  2. STATUS-GATED — a WORKING (or unreadable) lead is never touched.
  3. DEBOUNCED — idleAfterSeconds default 300.
  4. BOUNDED — quietNudgeCap default 3; stops nudging until real state returns; any new pending state resets the counter.
  5. NUDGE CARRIES STATE — reports pending replies (as exact bridge_poll(target=…) commands), DONE sessions, live workers; if nothing pending it says exactly that so the lead can stand down.
  6. NEVER DOUBLE-NUDGES — stands down (Action.STAND_DOWN) while ReplyPushLoop is actively nudging, via new ReplyPushLoop.isActive().

Changes: new msg/LeadHeartbeatLoop, config/BridgedConfig.LeadHeartbeat (defaults 300/60000/3, null ⇒ off), BridgedMetrics.HEARTBEAT_NUDGES, wiring in Bridged, bridged.example.yaml docs, and unit tests for the pure decide() + config.

Tests: full mvn clean install green: Tests run: 558, Failures: 0, Errors: 0, Skipped: 0. Base: origin/main @ 91c9f98.

Note: wiki/11-Features.md entry still due (submodule — not committable from the worker worktree).

## CB-551 — idle-lead heartbeat An opt-in heartbeat that nudges the single idle lead back to work once it has been continuously idle past a quiet period with no open bridge_send driving it. Mirrors the ReplyPushLoop pattern (pure unit-testable decide() + thin scheduler) with a different trigger. **Design constraints honored:** 1. **OPT-IN** — absent `leadHeartbeat:` config block ⇒ loop never constructed, feature fully off. 2. **STATUS-GATED** — a WORKING (or unreadable) lead is never touched. 3. **DEBOUNCED** — `idleAfterSeconds` default 300. 4. **BOUNDED** — `quietNudgeCap` default 3; stops nudging until real state returns; any new pending state resets the counter. 5. **NUDGE CARRIES STATE** — reports pending replies (as exact `bridge_poll(target=…)` commands), DONE sessions, live workers; if nothing pending it says exactly that so the lead can stand down. 6. **NEVER DOUBLE-NUDGES** — stands down (`Action.STAND_DOWN`) while ReplyPushLoop is actively nudging, via new `ReplyPushLoop.isActive()`. **Changes:** new `msg/LeadHeartbeatLoop`, `config/BridgedConfig.LeadHeartbeat` (defaults 300/60000/3, null ⇒ off), `BridgedMetrics.HEARTBEAT_NUDGES`, wiring in `Bridged`, `bridged.example.yaml` docs, and unit tests for the pure decide() + config. **Tests:** full `mvn clean install` green: Tests run: 558, Failures: 0, Errors: 0, Skipped: 0. Base: origin/main @ 91c9f98. > Note: wiki/11-Features.md entry still due (submodule — not committable from the worker worktree).
agent added 1 commit 2026-08-13 21:11:53 +02:00
CB-551: idle-lead heartbeat — nudge an idle lead back to work on a timer
CI / contract (pull_request) Successful in 43s
CI / build (pull_request) Successful in 56s
e5038c6d13
Owner

Closing as landed. Verified with git cherry main <branch>: every commit's content is present in main. The branch tip is not an ancestor only because the commit was rebased before merge, so the SHA differs while the patch is identical. No code is lost. Verified 2026-08-15.

Closing as **landed**. Verified with `git cherry main <branch>`: every commit's content is present in `main`. The branch tip is not an ancestor only because the commit was rebased before merge, so the SHA differs while the patch is identical. No code is lost. Verified 2026-08-15.
ltms closed this pull request 2026-08-15 07:10:59 +02:00
Some checks are pending
CI / contract (pull_request) Successful in 43s
CI / build (pull_request) Successful in 56s

Pull request closed

Sign in to join this conversation.