Skip to content

fix(kanban): isolate board override per concurrent call (CLI + dashboard)#39074

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-fadcb174
Jun 4, 2026
Merged

fix(kanban): isolate board override per concurrent call (CLI + dashboard)#39074
teknium1 merged 2 commits into
mainfrom
hermes/hermes-fadcb174

Conversation

@teknium1

@teknium1 teknium1 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

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: new scoped_current_board() contextmanager + _CURRENT_BOARD_OVERRIDE contextvar; get_current_board() checks it first, env-var path preserved for worker subprocesses. (@worlldz)
  • hermes_cli/kanban.py: CLI --board path uses the contextvar scope instead of mutating process-global HERMES_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 dashboard specify and decompose endpoints run as sync FastAPI threadpool handlers and mutated the same global env var. Two concurrent requests for different boards raced identically. Both now use scoped_current_board(); dropped the now-unused import 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 --board flag 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

Before After
CLI concurrent --board repro {'alpha': [], 'beta': ['beta-task','alpha-task']} {'alpha': ['alpha-task'], 'beta': ['beta-task']}
Dashboard endpoints concurrent (E2E, barrier-forced) would race on global env each thread resolves its own board, no cross-write
  • Contributor's regression test: 2 passed, 45 deselected
  • E2E: two threads held inside their scoped_current_board scope simultaneously (barrier), each get_current_board() resolved correctly, no cross-write.

Closes #38323. Supersedes #38325 (contributor authorship preserved via cherry-pick).

Infographic

isolate-board-override-per-concurrent-call

worlldz and others added 2 commits June 4, 2026 06:12
…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.
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-fadcb174 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 9837 on HEAD, 9837 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 5101 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have labels Jun 4, 2026
@teknium1 teknium1 merged commit 62f0cfd into main Jun 4, 2026
23 checks passed
@teknium1 teknium1 deleted the hermes/hermes-fadcb174 branch June 4, 2026 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: kanban --board uses process-global state and can cross-write tasks under concurrent calls

3 participants