Files
hermes-agent/hermes_cli
Ben 0a23537829 fix(kanban): discover profiles under HERMES_HOME, not hardcoded ~/.hermes
`list_profiles_on_disk()` in `hermes_cli/kanban_db.py` hardcoded
`Path.home() / ".hermes" / "profiles"` for the profile lookup,
ignoring `HERMES_HOME`. In the shipped Docker image where
`HERMES_HOME` points at the mounted volume (e.g. `/opt/data`) and the
container user's $HOME contains no .hermes directory, this returned
`[]` on every call — even when real profiles existed at
`<HERMES_HOME>/profiles/`.

That empty list cascades into two user-visible failures that both
present as "all kanban tasks stuck unassigned":

1. Dashboard assignee dropdown. `GET /kanban/assignees` calls
   `known_assignees()`, which unions `list_profiles_on_disk()` with
   currently-assigned names on the board. On a fresh Docker install,
   both sets are empty, so the dropdown is empty and the only tasks
   users can create from the web UI have `assignee=None`. The
   dispatcher (`dispatch_once()` in the same file) explicitly skips
   any ready task whose assignee is NULL and records them into
   `DispatchResult.skipped_unassigned` with no error — they sit in
   `ready` forever. Combined with `_default_spawn()` raising
   `ValueError` on missing assignee, unassigned tasks are structurally
   undispatchable.

2. `hermes kanban init` misdirection. The command printed
   "No profiles found under ~/.hermes/profiles/" regardless of the
   actual resolved path, sending Docker users down the wrong debugging
   path when their profiles were fine, just not being found.

Fix: route `list_profiles_on_disk()` through the existing
`kanban_home()` helper (already defined in the same module at line 84,
already correctly handles Docker via `get_default_hermes_root()`).
`_cmd_init` now prints the actually-resolved profiles directory
instead of a hardcoded path.

This matches the canonical pattern used by `hermes_cli/profiles.py`
(`_get_profiles_root` → `get_default_hermes_root`) and the explicit
note in `tests/conftest.py`:

    Any code in the codebase reading `~/.hermes/*` via
    `Path.home() / ".hermes"` instead of `get_hermes_home()` is a bug
    to fix at the callsite.

Tests:
- New `test_list_profiles_on_disk_docker_layout`: sets $HOME to a
  path with no .hermes dir, sets `HERMES_HOME` to a separate tempdir
  (the Docker layout), writes profiles under there, asserts discovery.
  Verified RED against the buggy code, GREEN against the fix.
- Existing `test_list_profiles_on_disk` updated to set `HERMES_HOME`
  explicitly. It was previously passing by accident because conftest's
  hermetic fixture sets `HERMES_HOME` to a different tempdir, and the
  buggy code path happened to align with the `Path.home()` monkeypatch.
  The new assertion is that profiles are discovered under the resolved
  `HERMES_HOME`, not under wherever `Path.home()` happens to point.

No other call sites in the kanban subsystem use `Path.home()` (grep
confirmed), so this is the only cascade point for the Docker symptom.
2026-05-04 16:00:17 +10:00
..
2026-04-24 12:07:46 -04:00
2026-04-29 20:33:29 -07:00