Skip to content

feat(gateway): add active-wake operator receipts - #49593

Closed
verybigdog wants to merge 6 commits into
NousResearch:mainfrom
verybigdog:contrib/active-wake-send-message-t_a11319e9
Closed

feat(gateway): add active-wake operator receipts#49593
verybigdog wants to merge 6 commits into
NousResearch:mainfrom
verybigdog:contrib/active-wake-send-message-t_a11319e9

Conversation

@verybigdog

@verybigdog verybigdog commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Reworks the older active-wake draft into the current ACK/active-wake receipt stack.
  • Keeps visible send delivery, scheduled wake, session acceptance/start, and operator receipt as separate states.
  • Routes trusted internal active-wake events to the intended gateway/operator session instead of a synthetic hermes-active-wake ghost session.
  • Persists ack_active_wake / ack_operator_receipt evidence for Kanban terminal ACKs.

Relationship to smaller PRs

This is the integration PR for the ACK/active-wake set. It intentionally depends on/supersets the smaller reviewable primitives:

The earlier draft only proved that an adapter wake was scheduled. This update adds honest receipt semantics (scheduled_agent, accepted_by_session, started_by_session, active_wake_status, target_session_key) and prevents treating triggered_agent as proof of operator observation.

Tests

  • python3 -m pytest tests/gateway/test_busy_session_auth_bypass.py tests/tools/test_send_message_tool.py::TestActiveWakeReceipt tests/hermes_cli/test_kanban_notify.py tests/gateway/test_api_server_runs.py::TestActiveWakeSmoke tests/hermes_cli/test_kanban_ack_ledger.py tests/hermes_cli/test_kanban_diagnostics.py -q -o addopts=
  • python3 -m py_compile gateway/run.py gateway/kanban_watchers.py gateway/platforms/api_server.py hermes_cli/kanban.py hermes_cli/kanban_db.py hermes_cli/kanban_db_ack_ledger.py hermes_cli/kanban_diagnostics.py tools/send_message_tool.py
  • git diff --check

Notes

  • Kept draft while the prerequisite PRs are reviewed; mark ready after maintainers are comfortable with the split or if they prefer one integration PR.

@alt-glitch alt-glitch added type/feature New feature or request comp/gateway Gateway runner, session dispatch, delivery comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have labels Jun 20, 2026
Hermes Agent added 6 commits June 20, 2026 18:25
(cherry picked from commit c0f1ead525b460c07265ce1a2aa884cf94d91c13)
(cherry picked from commit 527dae90249a2f428263f4e1c713d284b804f474)
(cherry picked from commit 2181f11f229ac8f3883323c737e8e5310fa47305)
(cherry picked from commit 3fc98272507a64dae29fa00644a6237ea14ed0d9)
(cherry picked from commit 722aedbf85058762686b479328d5c803d556bd89)
(cherry picked from commit 7add5c495782d2bbf82dce49ef182db3a99ca5f4)
(cherry picked from commit 61f3af9be0482e57aed81e25569e978ec1fc32e6)
(cherry picked from commit 0e3f42c136bfa536413c15970f6bab29ded4eb69)
Separate Kanban task verdicts from return-path delivery state by adding explicit ACK ledger records for subscriptions, passive delivery, active wake, and operator receipt state.

Stop inferring durable ACK subscriptions from prose Origin/return_to bodies; require explicit origin fields/notify subscriptions and preserve multi-subscription snapshots.

Wire Kanban notifier trigger_agent through sanitized active-wake receipts while keeping passive delivery and active wake outcomes distinct.

Tests: python3 -m pytest tests/hermes_cli/test_kanban_ack_ledger.py tests/hermes_cli/test_kanban_notify.py tests/hermes_cli/test_kanban_core_functionality.py -q -o addopts= (213 passed, 1 warning)
(cherry picked from commit 6de481461a69a2bce740607aed31791e1d16c17e)
(cherry picked from commit 5e6dbe53632d37a410eaae6a3bedc25088183cf1)
(cherry picked from commit 97c146cd87ad325c58348ea1029232c5c4259a47)
(cherry picked from commit 1b5d6a2282b292e4377e85e3ad1abc3446e64a84)
@verybigdog
verybigdog force-pushed the contrib/active-wake-send-message-t_a11319e9 branch from 4022e73 to c64baf1 Compare June 20, 2026 18:25
@verybigdog verybigdog changed the title feat(send-message): add explicit active wake receipts feat(gateway): add active-wake operator receipts Jun 20, 2026

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for separating passive delivery, scheduling, and session state. The current main limitation is real: gateway/kanban_watchers.py:517-533 says missing chat_type can route a DM creator into a fresh group session.

Problems

  • tools/send_message_tool.py:701 still unconditionally creates SessionSource(chat_type="group"). gateway/session.py:907-959 gives DMs a distinct :dm: session-key shape, so an active wake for a DM target can still create or target the wrong session. The added tests exercise group routing (tests/tools/test_send_message_tool.py:3228-3262), not this DM case.
  • gateway/kanban_watchers.py:606-614 writes ack_operator_receipt(status="observed") when a wake is merely accepted or started by a session. That is gateway execution evidence, not operator observation, and conflicts with the PR's stated receipt distinction.

Suggested changes

  • Persist/resolve trusted chat type and required identity before constructing a wake source; add DM and group-per-user routing coverage.
  • Reserve an observed operator receipt for an explicit acknowledgement, or label the existing row as session acceptance.

Automated hermes-sweeper review.

source = SessionSource(
platform=platform,
chat_id=str(chat_id),
chat_type="group",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This forces every active wake into the group key shape. build_session_key() uses a distinct :dm: shape for direct messages (gateway/session.py:907-915), so a DM target can wake a new group session rather than the intended operator session. Carry trusted chat_type/session identity or fail the wake when it cannot be resolved; add a DM regression test.

started_by_session=bool(payload.get("started_by_session")),
target_session_key=payload.get("target_session_key"),
)
if payload.get("accepted_by_session") or payload.get("started_by_session"):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accepted_by_session / started_by_session only show that Hermes accepted or began processing a synthetic event. They do not show that an operator observed it, so writing an ack_operator_receipt with status="observed" here overstates the evidence. Record a separate session-acceptance state, or require an explicit operator acknowledgement before this row.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
@verybigdog

Copy link
Copy Markdown
Contributor Author

Recommend absorbing the worthwhile parts of this PR and then closing it once they land. The core active-wake mechanism here duplicates #37865 but regresses it: SessionSource hardcodes chat_type=group (breaks DM routing that #37865 fixes by replaying chat_type, default 'dm'), trigger_agent/correlation_id are exposed on SEND_MESSAGE_SCHEMA (#37865 deliberately keeps wake non-model-exposed), and there is no non-default-profile fail-closed / no user_id_alt replay. The receipt vocabulary scheduled/accepted/started is sound, but 'observed' is written on agent accept/start, conflating execution evidence with operator observation — that should be reserved for an explicit operator acknowledgement. The ACK ledger is currently write-only (readers only in tests). The genuinely useful, self-contained subset — classify_ack_relay + the missing-ack-relay diagnostic — is being carried as the reviewed, standalone #49752, and the _sanitize_active_wake_text scrubber can be added to #37865 as optional hardening. Proposing closure AFTER #49752 lands and any snippet-hardening is cherry-picked; nothing is closed by this note. (This PR is not closed.)

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

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/tools Tool registry, model_tools, toolsets P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants