Skip to content

[Bug]: kanban workers spawned with -p <profile> use a profile-local kanban.db instead of the shared board #19348

@GodsBoy

Description

@GodsBoy

Bug Description

hermes_cli/kanban_db.py resolves kanban_db_path() and workspaces_root() through get_hermes_home(), which returns the active profile's HERMES_HOME. When the dispatcher spawns a worker with hermes -p <profile> --skills kanban-worker chat -q "work kanban task <id>", the worker's _apply_profile_override() rewrites HERMES_HOME to ~/.hermes/profiles/<profile> before kanban_db.py is imported, so the worker reads/writes a profile-local kanban.db instead of the shared board the dispatcher claimed against.

This contradicts the public docs (website/docs/user-guide/features/kanban.md: "Hermes Kanban is a durable task board, shared across all your Hermes profiles ... Every task is a row in ~/.hermes/kanban.db") and the kanban_db.py module docstring itself, which says "$HERMES_HOME/kanban.db (profile-agnostic on purpose:".

Steps to Reproduce

  1. On a host with at least one non-default profile (e.g. nehemiahkanban).
  2. Run the gateway with no profile so the dispatcher uses ~/.hermes/kanban.db.
  3. hermes kanban create "smoke" --assignee nehemiahkanban — task lands in ~/.hermes/kanban.db.
  4. Dispatcher claims the task and spawns hermes -p nehemiahkanban --skills kanban-worker chat -q "work kanban task <id>".
  5. Worker process resolves kanban_db_path() to ~/.hermes/profiles/nehemiahkanban/kanban.db (a different file).
  6. Worker's kanban_show <id> returns "task not found"; kanban_complete cannot find the task either; the dispatcher's row stays running and is retried/crashed.

Expected Behavior

Per the kanban docs, the board is shared across all profiles. A worker spawned with hermes -p <profile> must read and write the same kanban.db as the dispatcher that claimed the task. The same applies to workspaces_root() and the per-task log directory (<root>/kanban/logs/<task_id>.log) so kanban tooling and the dispatcher converge on a single set of paths.

Profile-specific config, .env, memory, and session state should remain isolated per profile (no change there).

Actual Behavior

Profile workers operate against a profile-local kanban.db that the dispatcher never wrote to:

  • Dispatcher (no profile): kanban_db_path() == ~/.hermes/kanban.db
  • Worker (-p nehemiahkanban): kanban_db_path() == ~/.hermes/profiles/nehemiahkanban/kanban.db

Reproduced on a Linux VPS with task t_0d214f19. After symlinking ~/.hermes/profiles/nehemiahkanban/kanban.db -> ~/.hermes/kanban.db, a follow-up smoke-test task t_93ef097d ran end-to-end and kanban_complete succeeded. The symlink is the user-side workaround.

Affected Component

CLI (interactive chat), Tools (terminal, file ops, web, code execution, etc.), Agent Core (conversation loop, context compression, memory)

Operating System

Linux (Ubuntu) VPS

Root Cause Analysis

hermes_cli/kanban_db.py:

def kanban_db_path() -> Path:
    """Return the path to ``kanban.db`` inside the active HERMES_HOME."""
    from hermes_constants import get_hermes_home
    return get_hermes_home() / "kanban.db"


def workspaces_root() -> Path:
    """Return the directory under which ``scratch`` workspaces are created."""
    from hermes_constants import get_hermes_home
    return get_hermes_home() / "kanban" / "workspaces"

get_hermes_home() returns the active profile's home. The kanban surface is a coordination primitive shared across profiles, so it has to anchor at the parent of <root>/profiles/<name> instead. This is the same architectural pattern as _get_profiles_root() in profile management code, which is intentionally HOME-anchored (see AGENTS.md § "Profiles: Multi-Instance Support" rule 6).

The _default_spawn log directory (get_hermes_home() / "kanban" / "logs") and the kanban log helper (<task_id>.log) have the same defect.

Proposed Fix

Resolve the kanban root through get_default_hermes_root() from hermes_constants.py, which already correctly returns <root> when HERMES_HOME is <root>/profiles/<name> (and falls through to HERMES_HOME for Docker / custom deployments). Add an explicit HERMES_KANBAN_HOME env-var override for tests and unusual deployments. Touch up the misleading docstrings in kanban_db.py and add a one-paragraph clarification to the kanban docs.

A regression test that mocks Path.home() and sets HERMES_HOME to a profile path (per the profile_env fixture in tests/hermes_cli/test_profiles.py) catches this on green.

I'd like to fix this myself and submit a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/cliCLI entry point, hermes_cli/, setup wizardtype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions