Keep initially blocked Kanban tasks sticky - #71861
Conversation
Duplicate of #34735: both add the create_task blocked-event marker required for initial-status blocked tasks to remain sticky through recompute_ready. |
|
Thanks for the focused regression fix. The premise is confirmed on current The added Automated hermes-sweeper review. |
GottZ
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Summary
Twenty-five PRs address or reference the same approval-gate failure introduced when #28414 added create-time blocked status without emitting the lifecycle event consumed by _has_sticky_block(). Most diffs either append that missing blocked event, infer stickiness from the created payload, or broaden the fix into claim, authorization, recovery, or archival semantics.
Related pull requests
- #27526 [closed]
related— (+88/-10) — superseded reference: introducedinitial_status="blocked"across the CLI, database, and tool surface, but emitted onlycreated; it remains relevant because its focused feature was salvaged through #28414 while unrelated changes were dropped. - #28414 [merged]
related— (+40/-8) — merged reference implementation: added the create-time blocked state but only appendedcreated, establishing the exact event-history gap that letsrecompute_ready()release the hold. - #32581
partial— (+96/-117) — close in favor of the source-aware fix: it removes blocked rows from recomputation entirely, which also disables intentional circuit-breaker recovery. Despite the keep_open review, that review itself identifies this contract regression and asks for a narrower current-main change. - #34735
best fix— (+123/-0) — keep open with a salvage path: appendblockedimmediately aftercreatedin the same transaction and retain its event-order, repeated-recompute, explicit-unblock, and done-parent tests. This is the recorded best fix for both #39609 and #47777, and its keep_open review confirms the exact current-main root cause. - #34756
related— (+190/-10) — author action: split out the final claim-boundary defense if still required, while dropping or redesigning_restore_sticky_block. The contributor review blocks the current form because it reverses supported manualblocked → readypromotion and predates the current retry guard. - #35832
fixes— (+354/-4) — author action: split the narrow create-timeblockedevent from archive/worker teardown hardening. The core event fix duplicates #34735, while the contributor review blocks the bundled teardown because Windows may signal an unverified recycled PID. - #39085
fixes— (+34/-0) — close as duplicate of #34735: the diff appends the same create-timeblockedevent with one recomputation regression. Despite its keep_open review, the review describes the salvage as the same mechanical event insertion already covered more completely by #34735. - #39832 [closed]
partial— (+67/-12) — closed duplicate of #34735: it modified_has_sticky_block()to infer the hold fromcreatedinstead of emitting the established lifecycle event, bypassing gateway notifications and stale-block diagnostics; the later closure explicitly selected #34735. - #41497
fixes— (+94/-0) — close as duplicate of #34735, preserving its dispatcher dry-run regression as optional test salvage. Despite the keep_open review and contributor LGTM, the production change is the identical create-time event insertion already exercised more broadly in #34735. - #43479 [closed]
fixes— (+4591/-96) — closed, still relevant only for its small create-time event hunk; the branch bundled extensive unrelated gateway, Discord, archival, dashboard, and memory-provider work and was withdrawn as not ready for public upstream due diligence. - #46274 [closed]
fixes— (+66/-0) — closed duplicate of #34735: it appends the sameblockedevent and tests parentless and done-parent holds, without adding a distinct correction to the reported cause. - #46565
fixes— (+26/-0) — close as duplicate of #34735: its database hunk is the same event append and its single regression is narrower. Despite the keep_open review, the contributor discussion explicitly identifies #34735 as the earliest open canonical implementation. - #48253 [closed]
partial— (+55/-5) — closed duplicate of #34735: it inferred stickiness from thecreatedpayload rather than publishing the establishedblockedevent, and the author closed it after validating the remaining bug on main. - #48437 [closed]
fixes— (+61/-0) — closed duplicate of #34735: it implements the identical event insertion with parent, repeated-recompute, and explicit-unblock tests; its approval remains useful corroboration, but the contributor review selected #34735 as canonical. - #60100 [closed]
fixes— (+45/-0) — closed duplicate of #34735: its event payload claimedrecurrences: 1while persistedblock_recurrencesremained zero. Despite the keep_open review, that review identified the state/audit inconsistency, and the author closed in favor of #34735. - #61890 [closed]
fixes— (+39/-0) — closed duplicate of #34735: it atomically emits the same lifecycle event and adds equivalent done-parent coverage, with no separate correction against the root cause. - #64830
partial— (+37/-12) — close as duplicate of #34735: it changes_has_sticky_block()to parsecreatedinstead of emittingblocked. Despite its keep_open review, the diff does not supply the lifecycle event required by gateway and diagnostic consumers, whereas #34735 does. - #66993
fixes— (+89/-0) — author action: split out the manual-promotionunblockedordering and rollback tests if that behavior is independently desired; the create-time event portion duplicates #34735. This preserves the useful scope recognized by its keep_open review without maintaining two copies of the root fix. - #69531
best fix— (+2451/-127) — author action: rebase onto main or split out the auditable authorization, fingerprint, claim-CAS, and attachment-sealing defenses from the minimal sticky-event correction. It is a recorded best fix for #39609; the visible keep_open review flagsprovider_override, while the displayed diff now includes that field and a same-model/different-provider regression, so that resolution should be revalidated on the rebased branch rather than discarded. - #69679
fixes— (+127/-13) — author action: rebase and correct creation-time recurrence initialization, or split out only the legacy/manual-promotion lifecycle work. The contributor review blocks the currentblock_recurrences = 1behavior because the first later same-kind block would incorrectly escalate to triage. - #70733
fixes— (+194/-0) — close the core event hunk as duplicate of #34735 and do not retain the broad existing-block annotation path. Despite the keep_open review, that review and the blocking contributor comment show the annotation matches circuit-breaker rows and would convert recoverablegave_upblocks into sticky holds. - #71147
partial— (+152/-2) — keep open with a salvage path limited to the idempotent legacy-row backfill: re-anchor its two regressions after the current test-file pruning, while consolidating the ordinary create-time event insertion with #34735. This follows its keep_open review and preserves its distinct legacy-reuse behavior. - #71861
partial— (+39/-0) — close as duplicate of #34735: both append the same create-timeblockedmarker, and #34735 has broader lifecycle coverage plus recorded best-fix status. Despite the keep_open review on #71861, that review itself identifies #34735 as the duplicate correction and describes #71861's only needed salvage as the same narrow insertion. - #71977
fixes— (+101/-0) — close as duplicate of #34735, with its real-dispatch non-spawn test available for test-only salvage. Despite the keep_open review, the production diff is the same lifecycle event insertion, and contributor discussion explicitly classifies it as duplicate work. - #72030 [closed]
fixes— (+45/-0) — closed duplicate of #34735: it appends the same event and adds narrower repeated-recompute coverage; the author explicitly closed it after identifying #34735 as the correct review target.
Duplicates
#39085, #41497, #46274, #46565, #48437, #60100, #61890, #71861, #71977, and #72030 implement substantially the same create-time blocked event as #34735. #39832, #48253, and #64830 instead infer stickiness from created and should not replace the lifecycle-consistent chain. #35832 and #43479 contain the same core fix inside unrelated supersets; #66993, #69531, #69679, #70733, and #71147 add separable lifecycle or authorization behavior.
Suggested consolidation
Close #71861 as duplicate of #34735, along with the remaining pure event-insertion duplicates, while keeping #34735 open with the concrete salvage path of transplanting its atomic created → blocked append and broader lifecycle tests onto current main. Preserve distinct work only through focused author action: salvage #71147's idempotent legacy-row backfill, split #66993's manual-promotion ordering if needed, and rebase or split #69531's auditable authorization defenses after revalidating the displayed provider_override coverage; do not carry forward #32581's circuit-breaker regression, #35832's unsafe Windows PID path, #69679's recurrence initialization, or #70733's overbroad annotation branch.
Complex graph
flowchart TD
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
I39609(["issue #39609 (open)"])
I47777(["issue #47777 (open)"])
subgraph Dup34735 ["PRs duplicating each other"]
P34735["PR #34735 (open)"]
P35832["PR #35832 (open)"]
P39085["PR #39085 (open)"]
P39832["PR #39832 (closed)"]
P41497["PR #41497 (open)"]
P43479["PR #43479 (closed)"]
P46274["PR #46274 (closed)"]
P46565["PR #46565 (open)"]
P48253["PR #48253 (closed)"]
P48437["PR #48437 (closed)"]
P60100["PR #60100 (closed)"]
P61890["PR #61890 (closed)"]
P64830["PR #64830 (open)"]
P70733["PR #70733 (open)"]
P71147["PR #71147 (open)"]
P71861["PR #71861 (open)"]
P71977["PR #71977 (open)"]
P72030["PR #72030 (closed)"]
end
P71861 -.->|partial| I39609
P71861 -.->|partial| I47777
class I39609 open
class I47777 open
class P34735 open
class P35832 open
class P39085 open
class P39832 closed
class P41497 open
class P43479 closed
class P46274 closed
class P46565 open
class P48253 closed
class P48437 closed
class P60100 closed
class P61890 closed
class P64830 open
class P70733 open
class P71147 open
class P71861 open
class P71977 open
class P72030 closed
class P34735 best
class P34735 best
class P71861 target
click I39609 "https://github.com/NousResearch/hermes-agent/issues/39609"
click I47777 "https://github.com/NousResearch/hermes-agent/issues/47777"
click P34735 "https://github.com/NousResearch/hermes-agent/pull/34735"
click P35832 "https://github.com/NousResearch/hermes-agent/pull/35832"
click P39085 "https://github.com/NousResearch/hermes-agent/pull/39085"
click P39832 "https://github.com/NousResearch/hermes-agent/pull/39832"
click P41497 "https://github.com/NousResearch/hermes-agent/pull/41497"
click P43479 "https://github.com/NousResearch/hermes-agent/pull/43479"
click P46274 "https://github.com/NousResearch/hermes-agent/pull/46274"
click P46565 "https://github.com/NousResearch/hermes-agent/pull/46565"
click P48253 "https://github.com/NousResearch/hermes-agent/pull/48253"
click P48437 "https://github.com/NousResearch/hermes-agent/pull/48437"
click P60100 "https://github.com/NousResearch/hermes-agent/pull/60100"
click P61890 "https://github.com/NousResearch/hermes-agent/pull/61890"
click P64830 "https://github.com/NousResearch/hermes-agent/pull/64830"
click P70733 "https://github.com/NousResearch/hermes-agent/pull/70733"
click P71147 "https://github.com/NousResearch/hermes-agent/pull/71147"
click P71861 "https://github.com/NousResearch/hermes-agent/pull/71861"
click P71977 "https://github.com/NousResearch/hermes-agent/pull/71977"
click P72030 "https://github.com/NousResearch/hermes-agent/pull/72030"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed (state tag in the node label).
Cross-PR triage: Reviewed 25 pull requests and 2 issues in this complex. Each diff was read against this issue; Assessment working set: 479 kB of PR diffs, 48 kB of issue/PR text, 30 kB of discussion (45 comments), 70 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.
What changed
blockedevent when a Kanban task is created withinitial_status="blocked".recompute_ready()does not promote the task.Root cause
The task row could be created in the blocked state without the event history used by
_has_sticky_block(). A later readiness recomputation therefore treated the initial block as non-sticky and could promote the task.User impact
Tasks intentionally created as blocked remain blocked until an explicit operator action changes that state.
Validation
mainin an isolated worktree.468 passed, 1 skippedacross the sticky-block regression and adjacent Kanban core, DB, init, repair, decompose, and specify suites.git diff --checkpassed.