fix(kanban): active_pr respawn guard honors an explicit unblock (carry #46204) - #15
Merged
Merged
Conversation
The active_pr respawn guard in check_respawn_guard refuses to spawn a ready task that has a GitHub PR URL in a recent comment (within the 24h _RESPAWN_GUARD_PR_WINDOW), to prevent a builder re-opening a duplicate PR. But in the one-card review lifecycle, when a reviewer bounces a card back to the author to rework the SAME PR, the card lands in status='ready' still carrying the build-handoff PR-URL comment — so the guard wedges the author out of spawning for up to 24h and the rework loop cannot complete. Use the latest 'unblocked' task event as an additional lower bound on the PR-comment scan window: PR URLs posted before a deliberate unblock no longer veto the respawn (the unblock is the operator/orchestrator's green light to resume work on that PR), while URLs at or after the unblock still guard against a genuine duplicate-PR. Same-second comments stay guarded conservatively (timestamps are second-granular). This is additive over the carried NousResearch#46549 (which bypasses the guard only for status='review'); the author-rework card is in 'ready', which NousResearch#46549 does not cover. Applied inside the existing `if not is_review:` block so the two compose. Carries the mechanism from upstream PR NousResearch#46204 by dannyfranca, adapted to this fork's line context (our base already wraps the active_pr block in the NousResearch#46549 is_review guard, so a raw cherry-pick would conflict). Adds 3 invariant tests and the matching docstring + kanban.md docs. Tracked in PATCHES.md and docs/patches/2026-06-28-pr46204-active-pr-unblock-cutoff.md; auto-retires when NousResearch#46204 merges upstream. Upstream-PR: NousResearch#46204 Upstream-Issue: NousResearch#29458 Co-authored-by: dannyfranca <dannyfranca@users.noreply.github.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.
What
Make the kanban
active_prrespawn guard honor an explicit unblock, so thereview→author rework loop can spawn the author without waiting out the 24h
PR window.
Why
check_respawn_guard'sactive_prguard refuses to spawn areadytask thathas a GitHub PR URL in a recent comment (24h window), to stop a builder
re-opening a duplicate PR. But when a reviewer bounces a card back to the author
to rework the same PR, the card lands in
status='ready'still carrying thebuild-handoff PR-URL comment — so the guard wedges the author out of spawning
for up to 24h and the inner rework loop can't complete autonomously.
Live symptom on this homestead: card
t_2c6bd5f2/ PR #68 — repeatedrespawn_guarded {'reason': 'active_pr'}, card stuckreadyafter a reviewbounce.
How
Use the latest
unblockedtask event as an additional lower bound on thePR-comment scan window (
pr_cutoff = max(window_start, latest_unblock_ts)):unblock is the operator/orchestrator's green light to resume on that PR.
The rework loop is then: reviewer ends with
kanban_block→ orchestratorunblocks + assigns the author → author spawns immediately.block/unblockare first-class CLI verbs, so this stays CLI-only.
Relationship to NousResearch#46549 (already carried)
Additive, not redundant. NousResearch#46549 bypasses the guard for
status='review'only;the author-rework card is in
ready, which NousResearch#46549 explicitly does not cover.The cutoff is applied inside the existing
if not is_review:block so thetwo compose.
Provenance
Carries the mechanism from upstream NousResearch#46204
(dannyfranca), adapted to this fork's line context (our base already wraps the
active_prblock in NousResearch#46549'sis_reviewguard, so a raw cherry-pick conflicts).Logic is byte-equivalent to upstream; placement differs to compose with NousResearch#46549.
Addresses upstream issue NousResearch#29458. Tracked in
PATCHES.md(upstream-pending) anddocs/patches/2026-06-28-pr46204-active-pr-unblock-cutoff.md; auto-retires whenNousResearch#46204 merges upstream.
Tests
same-second-conservative.
pytest tests/hermes_cli/test_kanban_db.py— 226 passed (no regression tofix(kanban): review tasks bypass dup-PR respawn guards (active_pr/recent_success) NousResearch/hermes-agent#46549's review-bypass invariants or the dispatch path).
website/docs/user-guide/features/kanban.mdupdates.