Skip to content

fix(kanban): share board, workspaces, and worker logs across profiles#19378

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-7aceb669
May 3, 2026
Merged

fix(kanban): share board, workspaces, and worker logs across profiles#19378
teknium1 merged 2 commits into
mainfrom
hermes/hermes-7aceb669

Conversation

@teknium1

@teknium1 teknium1 commented May 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Profile workers (hermes -p <name>) now share the same kanban board, workspaces, and worker-log directory as the dispatcher that spawned them — fixes #18442.

Root cause: kanban_db_path(), workspaces_root(), and the three worker-log-dir sites in hermes_cli/kanban_db.py all resolved paths through get_hermes_home(), which returns the active profile's HERMES_HOME. When the dispatcher spawned a worker with hermes -p <profile> chat -q "work kanban task <id>", the worker's _apply_profile_override() rewrote HERMES_HOME to ~/.hermes/profiles/<profile> and opened a profile-local kanban.db that didn't contain the dispatcher's task.

Changes

hermes_cli/kanban_db.py:

  • New kanban_home() helper resolves through HERMES_KANBAN_HOMEget_default_hermes_root(). get_default_hermes_root() already handles both <root>/profiles/<name> layouts and Docker / custom HERMES_HOME paths correctly.
  • kanban_db_path() honours HERMES_KANBAN_DB first, then kanban_home()/kanban.db.
  • workspaces_root() honours HERMES_KANBAN_WORKSPACES_ROOT first, then kanban_home()/kanban/workspaces.
  • _default_spawn log dir, gc_worker_logs, and worker_log_path() all route through kanban_home() — these three sibling sites were the log-dir tail end of the same bug.
  • _default_spawn() now injects HERMES_KANBAN_DB and HERMES_KANBAN_WORKSPACES_ROOT into the worker subprocess env. Defense-in-depth: even when the worker's get_default_hermes_root() resolution disagrees with the dispatcher's (unusual symlink / Docker layouts), the two processes still open the same SQLite file.
  • All three env overrides use .expanduser() for consistency.

hermes_cli/kanban.py: help string for log subcommand updated ($HERMES_HOME/kanban/logs/<kanban-root>/kanban/logs/).

tests/hermes_cli/test_kanban_db.py: 12 regression tests under TestSharedBoardPaths covering default install, profile-worker convergence, Docker custom root, Docker profile layout, HERMES_KANBAN_HOME override, per-path HERMES_KANBAN_DB and HERMES_KANBAN_WORKSPACES_ROOT pins, empty/whitespace overrides falling through, real SQLite cross-profile handoff, and dispatcher env-injection on spawn.

website/docs/reference/environment-variables.md: documents the three new kanban env vars.

Validation

Before After
hermes -p worker worker opens ~/.hermes/profiles/worker/kanban.db ~/.hermes/kanban.db
hermes kanban tail <id> from profile silent (empty file in profile dir) reads dispatcher's log
Docker /opt/hermes/profiles/x worker /opt/hermes/profiles/x/kanban.db /opt/hermes/kanban.db
Kanban targeted tests n/a 221 passed (test_kanban_db + test_kanban_cli + test_kanban_core_functionality + test_kanban_tools)
E2E (real imports, real SQLite) n/a 5/5 scenarios pass: dispatcher/worker converge, HERMES_KANBAN_DB pin wins, cross-profile SQLite handoff, dispatcher env injection

Consolidation

This PR fuses the best aspects of the seven parallel PRs that targeted #18442:

Closes #18300, #18503, #18670, #18985, #19037, #19056, #19100. Fixes #18442, closes #19348.

Test plan

scripts/run_tests.sh tests/hermes_cli/test_kanban_db.py tests/hermes_cli/test_kanban_cli.py tests/hermes_cli/test_kanban_core_functionality.py tests/tools/test_kanban_tools.py
# 221 passed

Manual repro (without fix):

  1. hermes kanban create "smoke" --assignee worker1
  2. Dispatcher spawns hermes -p worker1 ..., worker opens ~/.hermes/profiles/worker1/kanban.db, kanban_show fails, dispatcher retries forever.

After fix:

  1. Both sides resolve ~/.hermes/kanban.db; worker completes the task.
  2. HERMES_KANBAN_DB injected into the worker env guarantees this even if resolution inside the worker somehow disagreed.

GodsBoy and others added 2 commits May 3, 2026 15:02
…Hermes root

The Kanban board is documented as shared across all Hermes profiles, but
`kanban_db_path()` and `workspaces_root()` resolved through `get_hermes_home()`,
which returns the active profile's HERMES_HOME. When the dispatcher spawned a
worker with `hermes -p <profile> --skills kanban-worker chat -q "work kanban
task <id>"`, the worker rewrote HERMES_HOME to the profile subdirectory before
kanban_db.py imported, opening a profile-local `kanban.db` that did not contain
the dispatcher's task. `kanban_show` and `kanban_complete` failed; the
dispatcher's row stayed `running` and was retried/crashed. The same defect
applied to `_default_spawn`'s log directory and `worker_log_path`, so
`hermes kanban tail` did not see the worker's output.

Add `kanban_home()` in `hermes_cli/kanban_db.py` that resolves through
`HERMES_KANBAN_HOME` (explicit override) then `get_default_hermes_root()`,
which already understands the `<root>/profiles/<name>` and Docker / custom
HERMES_HOME shapes. Reroute `kanban_db_path`, `workspaces_root`, the
`_default_spawn` log directory, `gc_worker_logs`, and `worker_log_path`
through it. Profile-specific config, `.env`, memory, and sessions stay
isolated as before; only the kanban surface is shared.

Add a `TestSharedBoardPaths` regression class to `tests/hermes_cli/test_kanban_db.py`
covering: default install, profile-worker convergence, Docker custom HERMES_HOME,
Docker profile layout, explicit `HERMES_KANBAN_HOME` override, and a real
SQLite round-trip across dispatcher and worker HERMES_HOME perspectives.
The dispatcher/worker convergence tests fail on origin/main and pass after
the fix.

Update the `kanban.md` user-guide page and the misleading docstrings in
`kanban_db.py` to describe the shared-root behavior.

Fixes #19348
Layers defense-in-depth on top of the shared-root anchoring (base commit).

Changes in hermes_cli/kanban_db.py:
- kanban_db_path() now honours HERMES_KANBAN_DB first, then falls through
  to kanban_home()/kanban.db.
- workspaces_root() now honours HERMES_KANBAN_WORKSPACES_ROOT first, then
  falls through to kanban_home()/kanban/workspaces.
- All three overrides (HERMES_KANBAN_HOME, HERMES_KANBAN_DB,
  HERMES_KANBAN_WORKSPACES_ROOT) now call .expanduser() for consistency.
- _default_spawn() injects HERMES_KANBAN_DB and
  HERMES_KANBAN_WORKSPACES_ROOT into the worker subprocess env. Even
  when the worker's get_default_hermes_root() resolution somehow
  disagrees with the dispatcher's (symlinks, unusual Docker layouts),
  the two processes still open the same SQLite file.

Module docstring updated to describe all three overrides and the
dispatcher env-injection contract.

Tests (tests/hermes_cli/test_kanban_db.py, TestSharedBoardPaths):
- test_hermes_kanban_db_pin_beats_kanban_home
- test_hermes_kanban_workspaces_root_pin_beats_kanban_home
- test_empty_per_path_overrides_fall_through
- test_dispatcher_spawn_injects_kanban_db_and_workspaces_root
  (monkeypatches subprocess.Popen, asserts both env vars reach the
  child even after HERMES_HOME is rewritten by `hermes -p <profile>`.)

Docs: website/docs/reference/environment-variables.md gets entries
for the three kanban env vars.

This fusion is built on the cleanest of the seven competing PRs that
targeted issue #18442:

* Base commit (from PR #19350 by @GodsBoy): add `kanban_home()` helper
  anchored at `get_default_hermes_root()`, reroute all 5 kanban path
  sites through it (including the 3 sibling log-dir sites that the
  other six PRs missed), 8-test regression class.
* Dispatcher env-var injection approach drawn from PRs #18300
  (@quocanh261997) and #19100 (@cg2aigc).
* Per-path env overrides drawn from PR #19100 (@cg2aigc).
* get_default_hermes_root() resolution direction first proposed in
  PR #18503 (@beibi9966) and PR #18985 (@Gosuj).

Closes the duplicate/competing PRs: #18300, #18503, #18670, #18985,
#19037, #19056, #19100. Fixes #18442 and #19348.

Co-authored-by: quocanh261997 <17986614+quocanh261997@users.noreply.github.com>
Co-authored-by: cg2aigc <232694053+cg2aigc@users.noreply.github.com>
Co-authored-by: beibi9966 <beibei1988@proton.me>
Co-authored-by: Gosuj <123411271+Gosuj@users.noreply.github.com>
Co-authored-by: LeonSGP43 <154585401+LeonSGP43@users.noreply.github.com>
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels May 3, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing fix for #18442 — same root cause as #19100, #18985, #18300. This appears to be the most comprehensive of the bunch (covers kanban_db, workspaces, and worker logs).

@alt-glitch

Copy link
Copy Markdown
Collaborator

Competing fix for #18442 — same root cause as #19100, #18985, #18300.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

3 participants