fix(kanban): isolate board override per concurrent call (CLI + dashboard)#39074
Merged
Conversation
…se endpoints The dashboard specify and decompose endpoints run as sync FastAPI threadpool handlers and pinned the active board by mutating the process-global HERMES_KANBAN_BOARD env var. Two concurrent requests for different boards race on that shared global and cross-write — the same bug class as the CLI path (#38323), now using the scoped_current_board() contextvar introduced by the CLI fix.
Contributor
🔎 Lint report:
|
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.
Concurrent
kanban --board <slug> ...calls in the same process no longer cross-write tasks into the wrong board.Salvages #38325 (@worlldz, who also filed #38323) onto current
main, then widens the same fix to two sibling sites the original PR didn't touch.Changes
hermes_cli/kanban_db.py: newscoped_current_board()contextmanager +_CURRENT_BOARD_OVERRIDEcontextvar;get_current_board()checks it first, env-var path preserved for worker subprocesses. (@worlldz)hermes_cli/kanban.py: CLI--boardpath uses the contextvar scope instead of mutating process-globalHERMES_KANBAN_BOARD. (@worlldz)tests/hermes_cli/test_kanban_cli.py: barrier-based concurrency regression test. (@worlldz)plugins/kanban/dashboard/plugin_api.py: sibling fix — the dashboardspecifyanddecomposeendpoints run as sync FastAPI threadpool handlers and mutated the same global env var. Two concurrent requests for different boards raced identically. Both now usescoped_current_board(); dropped the now-unusedimport os.Root cause
get_current_board()read a process-global env var (HERMES_KANBAN_BOARD). Any path that pinned the board by mutating that global — the CLI--boardflag and the two dashboard endpoints — could be clobbered by a concurrent in-process call, landing writes on the wrong board. The contextvar override is thread/coroutine-local, so each call resolves only the board it requested.Validation
--boardrepro{'alpha': [], 'beta': ['beta-task','alpha-task']}{'alpha': ['alpha-task'], 'beta': ['beta-task']}2 passed, 45 deselectedscoped_current_boardscope simultaneously (barrier), eachget_current_board()resolved correctly, no cross-write.Closes #38323. Supersedes #38325 (contributor authorship preserved via cherry-pick).
Infographic