Bug Description
There is a critical identity leakage issue in the cron job scheduling system. When multiple scheduled tasks are executed, they can "cross-talk," meaning the output of one cron job is delivered to the target (user/channel) of another. This occurs because the system relies on process-global environment variables to track and resolve the delivery target for the current run.
Steps to Reproduce
- Configure two different cron jobs (Job A and Job B) with different delivery targets (e.g., User A and User B).
- Schedule both jobs to run at the same time or in very close succession.
- Trigger the scheduler (e.g., via the gateway's tick() loop).
- Observe that the results of Job A are occasionally delivered to User B, or vice versa.
Expected Behavior
Each cron job should operate in a fully isolated identity context. Regardless of how many jobs are running concurrently or sequentially, a job's output must only be delivered to its specifically configured target.
Actual Behavior
Delivery targets are leaked across jobs. The AI Agent may inadvertently send messages to the wrong channel because the tool responsible for delivery reads the target from a global environment variable that may have been overwritten by a different running job.
Affected Component
Agent Core (conversation loop, context compression, memory)
Messaging Platform (if gateway-related)
Telegram
Debug Report
Report https://paste.rs/22AMA
agent.log https://paste.rs/c4KZG
gateway.log https://paste.rs/CtCE7
Operating System
Ubuntu 24.04
Python Version
3.11.15
Hermes Version
0.9.0
Additional Logs / Traceback (optional)
The leakage follows this execution path:
1. cron/scheduler.py → run_job(): Sets global identity via os.environ["HERMES_CRON_AUTO_DELIVER_CHAT_ID"] = ...
2. model_tools.py → handle_function_call(): Dispatches tool calls but fails to pass the session_id or identity context to the tool handler.
3. tools/send_message_tool.py → _get_cron_auto_delivery_target(): Resolves the target using os.getenv("HERMES_CRON_AUTO_DELIVER_CHAT_ID").
4. If Job B has started and overwritten the environment variable while Job A is still executing its tool calls, Job A will deliver its result to Job B's target.
Root Cause Analysis (optional)
The root cause is the use of Process-Global State (os.environ) to store Session-Specific Metadata.
- In cron/scheduler.py, identity is injected into the global environment.
- In model_tools.py, the dispatch mechanism creates a "context gap" by not forwarding session identity to the tool handlers.
- In tools/send_message_tool.py, the tool blindly trusts the global environment to determine the recipient.
This architecture is fundamentally incompatible with any form of concurrency or rapid sequential execution, as os.environ is shared across all threads in the process.
Proposed Fix (optional)
- Eliminate Global Env Vars: Remove all os.environ injections of session/delivery metadata in cron/scheduler.py.
- Pass Identity Explicitly:
- Store the delivery target within the AIAgent instance or a session-scoped context object.
- Update model_tools.py to pass the session_id and associated identity metadata into the registry.dispatch call.
- Update Tool Resolution: Modify send_message_tool.py to retrieve the delivery target from the provided session context instead of calling os.getenv().
Are you willing to submit a PR for this?
Bug Description
There is a critical identity leakage issue in the cron job scheduling system. When multiple scheduled tasks are executed, they can "cross-talk," meaning the output of one cron job is delivered to the target (user/channel) of another. This occurs because the system relies on process-global environment variables to track and resolve the delivery target for the current run.
Steps to Reproduce
Expected Behavior
Each cron job should operate in a fully isolated identity context. Regardless of how many jobs are running concurrently or sequentially, a job's output must only be delivered to its specifically configured target.
Actual Behavior
Delivery targets are leaked across jobs. The AI Agent may inadvertently send messages to the wrong channel because the tool responsible for delivery reads the target from a global environment variable that may have been overwritten by a different running job.
Affected Component
Agent Core (conversation loop, context compression, memory)
Messaging Platform (if gateway-related)
Telegram
Debug Report
Operating System
Ubuntu 24.04
Python Version
3.11.15
Hermes Version
0.9.0
Additional Logs / Traceback (optional)
Root Cause Analysis (optional)
The root cause is the use of Process-Global State (os.environ) to store Session-Specific Metadata.
This architecture is fundamentally incompatible with any form of concurrency or rapid sequential execution, as os.environ is shared across all threads in the process.
Proposed Fix (optional)
Are you willing to submit a PR for this?