fix(heartbeat): _hb_wake no longer restarts an operator-parked agent (DIVE-4409) - #929
Merged
Merged
Conversation
…d agent (DIVE-4409) _hb_wake ran systemctl start on the agent unit inside 'if ! systemctl is-active' -- it started the unit precisely because it was not active -- and the dispatch loop that reaches it read no desiredState. A seat a person parked, holding one due todo, was resurrected every 15 minutes with no operator in the loop: DIVE-4033's consent failure on a third path, and the only one measurable on this host. The start now sits behind _hb_agent_is_parked, in DIVE-4033/DIVE-4399's shape: it SKIPS, it does not enforce, and only an explicit, parseable 'stopped' skips -- no registry, no jq, a corrupt body, an unknown agent and an absent field all start, because a wrong skip is the silent direction. A parked-but-running seat is untouched: a nudge into a live agent is not a resurrection. The skipped wake, unlike a skipped plugin bounce, leaves work OWED. The row stays todo and UNCLAIMED (a claim would strand it in_progress on a seat that never got the goal), the parked exit gets its own rc so neither caller reads it as a wake or as a retriable failure, the per-agent note is throttled to one line an hour, and the tick summary counts parked-skipped on every pass so the state is never invisible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ake ignores desiredState (DIVE-4409) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…gent Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… (DIVE-4409) The fence resolved the dispatch wake with `grep -n 'if _hb_wake "$name"' | tail -1`. When the dispatch site had to become `_hb_wake … || _wake_rc=$?` to read the parked exit code, that pattern stopped matching it and `tail -1` fell back to the `heartbeat wake-task` call site — a call nobody needs fenced. It reddened only by the accident of which line number came out larger; the other way round it would have gone green while guarding nothing. Both anchors are now matched by their distinctive ARGUMENTS (grep -F on `_hb_rotate_at_dispatch_boundary "$name" "$reg"` and `_hb_wake "$name" "$eff_fresh"`) and each must resolve to EXACTLY ONE line; 0 or 2+ matches is a loud FAIL, never a fallback. The resolver sets a global and returns a status rather than printing from `$( )`, because a subshell swallows both the message and the FAIL increment — which is how a broken fence goes quiet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Delivers DIVE-4409.
Opened by
5dive push --open-pr(DIVE-2605): the branch and this pull request went out on the same root-side rail, as 5dive-bot. The authoring agent holds no GitHub credential.