hermes - 💡(How to fix) Fix Kanban board ownership: replace global ambient current-board state with profile defaults and scoped dispatch

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Kanban board selection currently relies on too much global ambient state. A gateway profile can dispatch, notify, list, and write across boards that do not belong to that profile unless every call is manually pinned with --board / HERMES_KANBAN_BOARD.

This creates surprising cross-bot behavior: one profile can pick up or notify about tasks from another product/workstream's board, and /kanban operations inherit a global persisted current-board file rather than the bot/profile's natural default board.

Error Message

  • hermes kanban --board other create ... should work, but if other != default_board and allow_cross_board_writes=false, warn or require an explicit override flag such as --yes-cross-board / --cross-board.

Root Cause

Kanban board selection currently relies on too much global ambient state. A gateway profile can dispatch, notify, list, and write across boards that do not belong to that profile unless every call is manually pinned with --board / HERMES_KANBAN_BOARD.

This creates surprising cross-bot behavior: one profile can pick up or notify about tasks from another product/workstream's board, and /kanban operations inherit a global persisted current-board file rather than the bot/profile's natural default board.

Fix Action

Fix / Workaround

Kanban board selection currently relies on too much global ambient state. A gateway profile can dispatch, notify, list, and write across boards that do not belong to that profile unless every call is manually pinned with --board / HERMES_KANBAN_BOARD.

  • Each bot/profile has its own default Kanban board.
    • classifieds_bot / Clasi → classifieds_bot_board
    • governator_bot/Governator → governator_board
    • Skippy → likely skippy
    • Hermes core / root gateway → hermes
  • Bots can list all boards.
  • Bots can explicitly switch or use another board.
  • Cross-board writes should be deliberate, visible, and preferably warned.
  • Dispatchers should only scan boards they own or are explicitly configured to handle.
  1. The embedded gateway dispatcher iterates all boards on every tick:
    • gateway/run.py::_kanban_dispatcher_watcher
    • _tick_once() calls list_boards(include_archived=False) and dispatch_once() for every board.

Code Example

kanban:
  default_board: governor        # board used by this profile's /kanban and tools when no --board supplied
  dispatch_boards: [governor]    # boards this gateway dispatcher may scan
  notify_boards: [governor]      # boards this gateway notifier may poll
  allow_cross_board_writes: false

---

kanban:
  dispatch_boards: ["*"]
RAW_BUFFERClick to expand / collapse

Summary

Kanban board selection currently relies on too much global ambient state. A gateway profile can dispatch, notify, list, and write across boards that do not belong to that profile unless every call is manually pinned with --board / HERMES_KANBAN_BOARD.

This creates surprising cross-bot behavior: one profile can pick up or notify about tasks from another product/workstream's board, and /kanban operations inherit a global persisted current-board file rather than the bot/profile's natural default board.

Expected design

  • Each bot/profile has its own default Kanban board.
    • classifieds_bot / Clasi → classifieds_bot_board
    • governator_bot/Governator → governator_board
    • Skippy → likely skippy
    • Hermes core / root gateway → hermes
  • Bots can list all boards.
  • Bots can explicitly switch or use another board.
  • Cross-board writes should be deliberate, visible, and preferably warned.
  • Dispatchers should only scan boards they own or are explicitly configured to handle.

Current behavior / problem

The implementation has multiple ambient-global board selectors:

  1. hermes_cli.kanban_db.get_current_board() resolves:

    • HERMES_KANBAN_BOARD
    • then shared <kanban-root>/kanban/current
    • then default
  2. hermes kanban boards switch <slug> writes a shared current-board file, not a profile-scoped preference. Any profile or gateway process that does not set HERMES_KANBAN_BOARD can silently inherit that board.

  3. The embedded gateway dispatcher iterates all boards on every tick:

    • gateway/run.py::_kanban_dispatcher_watcher
    • _tick_once() calls list_boards(include_archived=False) and dispatch_once() for every board.
  4. The gateway notifier also iterates all boards:

    • gateway/run.py::_kanban_notifier_watcher
    • polls every board and delivers terminal events for subscriptions.
  5. /kanban slash command delegates to run_slash without a per-profile board default, so a bot's /kanban list/create/show can land on whatever ambient board is active unless explicitly pinned.

Why this is dangerous

  • Cross-board writes are easy and silent.
  • Dispatchers can spend tokens on boards unrelated to the profile hosting the dispatcher.
  • Notifications and blocked/done messages can appear in the wrong bot/channel context.
  • The user's mental model is per-bot ownership; the implementation behaves like a shared global queue.

Proposed design

Config

Introduce profile-level Kanban config:

kanban:
  default_board: governor        # board used by this profile's /kanban and tools when no --board supplied
  dispatch_boards: [governor]    # boards this gateway dispatcher may scan
  notify_boards: [governor]      # boards this gateway notifier may poll
  allow_cross_board_writes: false

Recommended defaults:

  • If kanban.default_board exists, use it.
  • Else infer from profile name when safe:
    • klasificadosklasificados
    • nagovernor / governorgovernor
    • skippyskippy
    • root/no profile → hermes
  • Else fallback to default for backward compatibility, but log a warning.

CLI / slash command

  • hermes kanban list and /kanban list should use profile kanban.default_board when no --board is supplied.
  • hermes kanban boards list should still list all boards.
  • hermes kanban --board other create ... should work, but if other != default_board and allow_cross_board_writes=false, warn or require an explicit override flag such as --yes-cross-board / --cross-board.

Dispatcher

  • Embedded gateway dispatcher should scan only kanban.dispatch_boards.
  • If unset, scan [kanban.default_board], not all boards.
  • A special explicit value can preserve old behavior:
kanban:
  dispatch_boards: ["*"]

Notifier

  • Embedded notifier should poll only kanban.notify_boards.
  • If unset, poll [kanban.default_board].
  • If ["*"], keep old fan-out behavior.

Acceptance criteria

  • Add config loader/helper for resolving a profile's kanban default board and owned board lists.
  • Update CLI/slash command board resolution to prefer profile default over shared global kanban/current.
  • Update embedded dispatcher so it does not enumerate all boards unless explicitly configured.
  • Update embedded notifier similarly.
  • Add tests for:
    • profile default board resolution
    • dispatcher scans only configured boards
    • dispatch_boards: ["*"] preserves old behavior
    • slash command / CLI create/list use profile default board
    • cross-board write warning/guard
  • Document migration/backward compatibility.

Related cleanup

The shared <kanban-root>/kanban/current file should probably become CLI-only human convenience, not gateway/profile runtime state. Profile gateways should not depend on it.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - 💡(How to fix) Fix Kanban board ownership: replace global ambient current-board state with profile defaults and scoped dispatch