fix(kanban): let PR feedback unblock respawn guard - #46204
Conversation
|
This is a great solution for this annoying problem. The approach makes sense. When the user manually unblocks a task, then the mentions of a PR in older messages should be disregarded, only the messages after the manual unblock matter for the next iteration. I reviewed the PR and tried it out on my local install, and it works perfectly. Thanks very much, this makes reviewing PRs much smoother! |
|
Addresses #29458 by making stale/closed |
Thanks, man. If you work with PRs on Kanban, then this should also be a good combo for you: https://github.com/dannyfranca/hermes-github-pr-kanban-bridge, I use it to automatically react and move the Kanban back to ready when a comment is left. I initially thoght about doing it webhook-based, but polling is totally fine if you can afford up to a minute delay to get a ticket to ready. It was initially vibe coded, but I have hardened it over time. Has been pretty stable for me. |
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>
Make the active_pr respawn guard honor an explicit unblock so the review->author rework loop can spawn without waiting out the 24h PR window. Uses the latest unblocked task event as an additional lower bound on the PR-comment scan window (pr_cutoff = max(window, latest_unblock_ts)): PR URLs posted before a deliberate unblock no longer veto respawn, while URLs at/after still guard. Additive over NousResearch#46549 (which covers status='review' only; the author-rework card is in 'ready'). upstream-pending: PR NousResearch#46204
|
Thanks for the focused respawn-guard fix. The premise still reproduces on current main: The proposed latest-unblock cutoff is a narrow fit for that defect and the added before/after/same-second cases cover the intended boundary. Current main has since added the adjacent This is an automated hermes-sweeper review. |
|
Nice fix — the unblock cutoff is the right shape for the rework case, and I'd like to see it land. One gap worth naming, since this PR and #29458 are becoming the focal point for the guard: both the cutoff here and the PR-state validation discussed there assume the matched URL belongs to the task's own PR. There's a third case where neither helps — a PR URL that arrives inside content the task fetched (release notes, a quoted changelog, an ingested web document). The task never opened a PR and was never blocked, so there is no unblocked event for the cutoff to anchor on; the card simply parks for 24 h on its first dispatch. We hit this in the wild with a fetched GitHub release body citing an unrelated PR. I filed that, plus an operator-facing window override, as #67249. I see the deliberate "no new config" stance here and I'm not suggesting this PR change — the knob would be a separate change; patch and tests are in that issue if it's wanted. |
Make the active_pr respawn guard honor an explicit unblock so the review->author rework loop can spawn without waiting out the 24h PR window. Uses the latest unblocked task event as an additional lower bound on the PR-comment scan window (pr_cutoff = max(window, latest_unblock_ts)): PR URLs posted before a deliberate unblock no longer veto respawn, while URLs at/after still guard. Additive over NousResearch#46549 (which covers status='review' only; the author-rework card is in 'ready'). upstream-pending: PR NousResearch#46204 (cherry picked from commit e741b78)
What does this PR do?
Fixes a Kanban dispatcher edge case where a task can remain stuck in
readyafter being explicitly unblocked for GitHub PR feedback.Today, the
active_prrespawn guard scans recent Kanban comments for raw GitHub PR URLs. That correctly prevents duplicate PR-producing workers, but it also means an older worker handoff comment likehttps://github.com/.../pull/123can keep blocking a later bridge/operator unblock whose purpose is to wake the same task to address fresh PR review feedback.This change makes the
active_prguard use the latestunblockedtask event as an additional cutoff:active_pr, preserving the duplicate-PR protection.This keeps the existing safety behavior without adding new config, environment variables, tools, or manual cleanup commands.
Related Issue
Related to #29458.
This does not close #29458 entirely because that issue also discusses broader operator clear paths and closed-PR handling. This PR fixes the narrower PR-feedback wake-up case where an explicit unblock should supersede older PR handoff URLs.
Type of Change
Changes Made
hermes_cli/kanban_db.pycheck_respawn_guard()soactive_pronly considers raw GitHub PR URLs at or after the latestunblockedevent.rate_limit_cooldown,blocker_auth, andrecent_success.created_at >= cutoff, because task events/comments are stored with second-level timestamps.tests/hermes_cli/test_kanban_db.pyactive_pr.dispatch_once()integration test proving a PR-feedback unblock can spawn once the only raw PR URL is older than the unblock.website/docs/user-guide/features/kanban.mdactive_prrespawn guard semantics.How to Test
Run the targeted Kanban DB regression suite:
Observed result:
Run the Windows compatibility footgun checker on the changed Python files:
Observed result:
Check whitespace/diff cleanliness:
Observed result: no output / clean.
Optional live smoke check on a board with the affected state:
A task with only pre-unblock raw PR URLs should now return
None; a PR URL at or after the latest unblock should still returnactive_pr.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passpython -m pytest tests/hermes_cli/test_kanban_db.py -q→218 passed, 1 warningDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/Ascripts/check-windows-footguns.pyon the changed Python files.Screenshots / Logs
Targeted regression suite:
Windows footgun check: