Bug Description
I found a real cross-board write corruption bug in the kanban CLI path.
hermes kanban --board <slug> ... currently pins the requested board by mutating the process-global HERMES_KANBAN_BOARD environment variable for the duration of the call.
That works in single-threaded use, but it is not safe when multiple kanban calls run concurrently in the same process. A second call can overwrite the board pin while the first call is still in progress, which makes writes land on the wrong board.
What I expected instead was for the board override to be isolated to the current call context rather than shared through process-global mutable state.
Steps to Reproduce
- Start from current
main
- Use a single process with a temporary
HERMES_HOME
- Create two boards, for example
alpha and beta
- Start two concurrent kanban calls in the same process:
kanban --board alpha create alpha-task
kanban --board beta create beta-task
- Observe where the tasks actually land
In my threaded repro on current main, both commands succeeded, but the resulting board state was:
{'alpha_titles': [], 'beta_titles': ['beta-task', 'alpha-task']}
So alpha-task was written to the wrong board.
Expected Behavior
Concurrent kanban --board ... calls in the same process should stay isolated and only read/write the board they explicitly requested.
Actual Behavior
Concurrent calls can overwrite each other’s board pin and cross-write tasks into the wrong board.
Representative repro result on current main:
{'alpha_titles': [], 'beta_titles': ['beta-task', 'alpha-task']}
Affected Component
CLI (interactive chat)
Messaging Platform (if gateway-related)
No response
Debug Report
Report https://paste.rs/9iy99
agent.log https://paste.rs/saClZ
gateway.log https://paste.rs/Agtu9
Operating System
Ubuntu on WSL2 (Windows 11)
Python Version
Python 3.12.3
Hermes Version
Hermes Agent v0.15.1 (2026.5.29)
Additional Logs / Traceback (optional)
This is a concurrent state-isolation bug rather than a traceback-only failure.
Both commands returned success, but one task was written into the other board because the board override was stored in process-global environment state instead of a per-call context.
Root Cause Analysis (optional)
In hermes_cli.kanban.kanban_command, --board is implemented by temporarily mutating HERMES_KANBAN_BOARD in os.environ.
hermes_cli.kanban_db.get_current_board() then reads that process-global environment variable to resolve the active board.
Because os.environ is shared across threads in the same process, concurrent kanban calls can overwrite each other’s board override mid-call and cause later DB operations to resolve the wrong board.
Proposed Fix (optional)
Replace the process-global board override for in-process kanban calls with a context-local override, while keeping the environment variable path for spawned worker processes and explicit external overrides.
I also prepared regression coverage that runs two concurrent kanban --board ... create calls in the same process and verifies each task lands on the correct board.
Are you willing to submit a PR for this?
Bug Description
I found a real cross-board write corruption bug in the kanban CLI path.
hermes kanban --board <slug> ...currently pins the requested board by mutating the process-globalHERMES_KANBAN_BOARDenvironment variable for the duration of the call.That works in single-threaded use, but it is not safe when multiple kanban calls run concurrently in the same process. A second call can overwrite the board pin while the first call is still in progress, which makes writes land on the wrong board.
What I expected instead was for the board override to be isolated to the current call context rather than shared through process-global mutable state.
Steps to Reproduce
mainHERMES_HOMEalphaandbetakanban --board alpha create alpha-taskkanban --board beta create beta-taskIn my threaded repro on current main, both commands succeeded, but the resulting board state was:
{'alpha_titles': [], 'beta_titles': ['beta-task', 'alpha-task']}So
alpha-taskwas written to the wrong board.Expected Behavior
Concurrent
kanban --board ...calls in the same process should stay isolated and only read/write the board they explicitly requested.Actual Behavior
Concurrent calls can overwrite each other’s board pin and cross-write tasks into the wrong board.
Representative repro result on current main:
{'alpha_titles': [], 'beta_titles': ['beta-task', 'alpha-task']}Affected Component
CLI (interactive chat)
Messaging Platform (if gateway-related)
No response
Debug Report
Operating System
Ubuntu on WSL2 (Windows 11)
Python Version
Python 3.12.3
Hermes Version
Hermes Agent v0.15.1 (2026.5.29)
Additional Logs / Traceback (optional)
This is a concurrent state-isolation bug rather than a traceback-only failure. Both commands returned success, but one task was written into the other board because the board override was stored in process-global environment state instead of a per-call context.Root Cause Analysis (optional)
In
hermes_cli.kanban.kanban_command,--boardis implemented by temporarily mutatingHERMES_KANBAN_BOARDinos.environ.hermes_cli.kanban_db.get_current_board()then reads that process-global environment variable to resolve the active board.Because
os.environis shared across threads in the same process, concurrent kanban calls can overwrite each other’s board override mid-call and cause later DB operations to resolve the wrong board.Proposed Fix (optional)
Replace the process-global board override for in-process kanban calls with a context-local override, while keeping the environment variable path for spawned worker processes and explicit external overrides.
I also prepared regression coverage that runs two concurrent
kanban --board ... createcalls in the same process and verifies each task lands on the correct board.Are you willing to submit a PR for this?