feat(gateway): add active-wake operator receipts - #49593
Conversation
(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)
4022e73 to
c64baf1
Compare
teknium1
left a comment
There was a problem hiding this comment.
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:701still unconditionally createsSessionSource(chat_type="group").gateway/session.py:907-959gives 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-614writesack_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", |
There was a problem hiding this comment.
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"): |
There was a problem hiding this comment.
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.
|
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.) |
Summary
hermes-active-wakeghost session.ack_active_wake/ack_operator_receiptevidence 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 treatingtriggered_agentas 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.pygit diff --checkNotes