Skip to content

fix: keep initially blocked kanban cards sticky - #60100

Closed
jowthean wants to merge 1 commit into
NousResearch:mainfrom
jowthean:fix/kanban-initial-blocked-sticky
Closed

fix: keep initially blocked kanban cards sticky#60100
jowthean wants to merge 1 commit into
NousResearch:mainfrom
jowthean:fix/kanban-initial-blocked-sticky

Conversation

@jowthean

@jowthean jowthean commented Jul 7, 2026

Copy link
Copy Markdown

Summary

  • emit a sticky blocked event when a Kanban task is created with initial_status="blocked"
  • prevent recompute_ready() from silently promoting create-time blocked cards to ready
  • add a regression test covering --initial-status blocked drift

Root cause

create_task(..., initial_status="blocked") inserted status="blocked" but only emitted a created event. _has_sticky_block() distinguishes human/ops blocks from transient blocks by looking for latest blocked/unblocked events, so create-time blocked cards looked non-sticky and were auto-promoted.

Test plan

  • uv run --with pytest --with pytest-xdist python -m pytest tests/hermes_cli/test_kanban_blocked_sticky.py::test_initial_status_blocked_is_not_auto_promoted_by_recompute_ready tests/hermes_cli/test_kanban_blocked_sticky.py tests/hermes_cli/test_kanban_db.py::test_recompute_ready_skips_tasks_at_failure_limit -q -n 0

Result: 8 passed.

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

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #34735 — same fix: emit a blocked event in create_task() when initial_status="blocked" so _has_sticky_block() recognises the card and recompute_ready() doesn't auto-promote it. #34735 is the earliest-open canonical of the sticky-block cluster (#39085, #41497, #46565, #48437). Maintainer to pick the winner.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the focused fix. The premise is still present on current main: create_task() sets task_status = "blocked" for initial_status="blocked" at hermes_cli/kanban_db.py:2585, but emits only created at hermes_cli/kanban_db.py:2670-2684. _has_sticky_block() requires a blocked/unblocked event (hermes_cli/kanban_db.py:3273-3279), so recompute_ready() can promote the card (hermes_cli/kanban_db.py:3317-3365).

Problems

  • The new event records "recurrences": 1, but the task row retains the schema default block_recurrences = 0 (hermes_cli/kanban_db.py:1173-1179). The loop-breaker reads that persisted field when a task is re-blocked (hermes_cli/kanban_db.py:4808-4818, 4873-4876), so the event audit payload and state machine disagree.

Suggested changes

  • Initialize the persisted recurrence state consistently and cover unblock → re-block, or omit recurrences from the creation event payload.

Automated hermes-sweeper review.

Comment thread hermes_cli/kanban_db.py
"kind": None,
"recurrences": 1,
},
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

block_recurrences remains at the task schema default of 0, while block_task() later reads that column to calculate re-block loops. Either initialize the task row consistently or omit this event-only recurrences value so the lifecycle audit does not claim state the loop breaker cannot see.

@teknium1 teknium1 added the sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform label Jul 15, 2026
@jowthean

Copy link
Copy Markdown
Author

Closing this in favour of #34735, the earliest open canonical PR for the same create-time sticky-block fix.

Our local deployment independently reproduced the defect and confirmed that emitting a blocked event prevents recompute_ready() from promoting an explicitly parked card. #34735 now has the more complete lifecycle coverage and avoids the recurrences event/persisted-state inconsistency identified in the sweeper review. Consolidating there should reduce duplicate maintainer work.

Thanks for the triage and review.

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-moderate Sweeper blast radius: moderate — a subsystem or single platform type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants