Skip to content

fix(kanban): profile-correct notification ownership and routing (salvage #57995, #56589, #62380, #69181) - #72241

Merged
teknium1 merged 4 commits into
mainfrom
pr/kanban-profile-ownership
Jul 26, 2026
Merged

fix(kanban): profile-correct notification ownership and routing (salvage #57995, #56589, #62380, #69181)#72241
teknium1 merged 4 commits into
mainfrom
pr/kanban-profile-ownership

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Multi-profile kanban notifications now route to the profile that created them — never a wrong bot, never a silent rewind loop. Four composed contributor fixes (one commit each, authorship preserved) close the ownership gaps on the shared board: subscriptions always get an owner stamp, the notifier no longer silently loses secondary-profile events, gateway-per-profile deployments resolve their own adapter instead of failing closed forever, and dispatched workers can't inherit stale session routing.

Fixes #57993, #71340, #70179. Partially addresses #56802 (items 2–3; item 1 — decoupling the notifier from kanban.dispatch_in_gateway — stays open as a design decision).

Changes

Not taken, for the record: #70091's dispatch_in_gateway gate removal (would resurrect the N-gateway SQLite contention the gate prevents; its other goals are covered here or already on main), #66703 and #69020 (separate design decisions, left open).

One noted edge for maintainer judgment: an explicit profile="default" stamp on a named-primary gateway still resolves via self.adapters — changing that would break every legacy default-stamped row, so it's left as-is.

Validation

Check Result
8 targeted suites after rebase onto current main 185/185 pass
Builder's full run 397/397 pass
Sabotage checks — each of the 4 fixes reverted individually → its regression test fails → restored all verified
ruff + git diff --check clean

Infographic

kanban-profile-ownership

@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 47597e9

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

1 visual diff.

inline evidence upload failed.

Failed to upload diff-665a0833239e-onboarding-overlay-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-665a0833239e-onboarding-overlay-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso)

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery comp/cron Cron scheduler and job management sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 26, 2026
@teknium1
teknium1 force-pushed the pr/kanban-profile-ownership branch from 806780b to 1957733 Compare July 26, 2026 23:05
tymrtn and others added 4 commits July 26, 2026 16:16
_collect()'s active_platforms pre-filter was derived solely from
self.adapters (the default profile), so a subscription owned by a
secondary profile on a platform the default profile never connected
(e.g. beta owns discord, default has no discord adapter at all) was
skipped before claim_unseen_events_for_sub ever ran. Unlike the
disconnected-adapter path, an unclaimed event is never rewound, so this
was a permanent, silent notification/wake loss — directly contradicting
the point of routing notifications via the owning profile
(c696430/b225b30d0). Same cross-profile-adapter-lookup bug class the
delivery-side _authorization_adapter chokepoint already guards against,
one gate earlier. The precise per-profile check still runs unchanged at
delivery time, with its existing rewind-on-None safety net.
A gateway running under a named active profile (e.g. `hermes -p main gateway`)
stamps kanban auto-subscriptions with notifier_profile=main, but
_authorization_adapter() treated any name other than the literal "default"
as a multiplex secondary and consulted only _profile_adapters — empty on
standalone gateway-per-profile deployments. The helper failed closed, the
notifier rewound the claim, and the notification was silently retried
forever (#71340).

Recognize the gateway's own active profile name as primary so its stamped
subscriptions resolve via self.adapters; genuinely secondary profiles keep
the fail-closed lookup.

Salvaged from PR #62380 (the unrelated blocked-reason truncation change is
intentionally not taken).
A long-lived gateway can have platform routing (HERMES_SESSION_* /
HERMES_CRON_AUTO_DELIVER_*) mirrored in os.environ from a previous turn.
_default_spawn() copied that process environment verbatim into detached
kanban workers, so a worker calling kanban_create treated the inherited
chat/topic as its origin and auto-subscribed the child task — the task's
terminal notification then woke an unrelated chat.

Strip every registered session-context routing key from the worker env
unconditionally (the dispatcher is detached from every conversation);
board, workspace, task, branch, profile, model, and credential
propagation are unchanged.

Salvaged from PR #69181 (both commits squashed; the PR's second commit
fixed the first's engagement-latch assumption).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kanban auto-subscribe can leak notifications across profiles

6 participants