Skip to content

Keep initially blocked Kanban tasks sticky - #71861

Draft
clutran78 wants to merge 1 commit into
NousResearch:mainfrom
clutran78:agent/sticky-blocked-kanban-20260726
Draft

Keep initially blocked Kanban tasks sticky#71861
clutran78 wants to merge 1 commit into
NousResearch:mainfrom
clutran78:agent/sticky-blocked-kanban-20260726

Conversation

@clutran78

Copy link
Copy Markdown

What changed

  • Records an explicit blocked event when a Kanban task is created with initial_status="blocked".
  • Adds a regression test proving the initial block is sticky and that 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

  • Replayed as a two-file commit on current upstream main in an isolated worktree.
  • 468 passed, 1 skipped across the sticky-block regression and adjacent Kanban core, DB, init, repair, decompose, and specify suites.
  • git diff --check passed.
  • No live Kanban task data was accessed or mutated by the publication work.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cron Cron scheduler and job management duplicate This issue or pull request already exists labels Jul 26, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #34735: both add the create_task blocked-event marker required for initial-status blocked tasks to remain sticky through recompute_ready.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused regression fix. The premise is confirmed on current main: create_task() writes status="blocked" for initial_status="blocked" at hermes_cli/kanban_db.py:3084-3089, but emits only the created event at hermes_cli/kanban_db.py:3172-3190. _has_sticky_block() therefore has no lifecycle marker at hermes_cli/kanban_db.py:3979-3985, and recompute_ready() can promote the card at hermes_cli/kanban_db.py:4030-4064.

The added blocked event directly supplies the signal consumed by the existing guard, and the regression test verifies both event order and the non-promotion behavior. The maintainer discussion identifies open #34735 as a duplicate with the same production correction and broader lifecycle tests. GitHub currently reports this draft as conflicting, but the needed salvage is a narrow placement after the current created event.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 30, 2026

@GottZ GottZ left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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: introduced initial_status="blocked" across the CLI, database, and tool surface, but emitted only created; 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 appended created, establishing the exact event-history gap that lets recompute_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: append blocked immediately after created in 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 manual blocked → ready promotion and predates the current retry guard.
  • #35832 fixes — (+354/-4) — author action: split the narrow create-time blocked event 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-time blocked event 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 from created instead 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 same blocked event 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 the created payload rather than publishing the established blocked event, 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 claimed recurrences: 1 while persisted block_recurrences remained 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 parse created instead of emitting blocked. 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-promotion unblocked ordering 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 flags provider_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 current block_recurrences = 1 behavior 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 recoverable gave_up blocks 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-time blocked marker, 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 createdblocked 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"
Loading

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants