Skip to content

fix(cron): scope cron approval context per session - #77022

Merged
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix/cron-session-isolation
Aug 2, 2026
Merged

fix(cron): scope cron approval context per session#77022
kshitijk4poor merged 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix/cron-session-isolation

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Cron approval state no longer leaks from a cron tick into unrelated gateway/API/TUI sessions running in the same process. The process-global HERMES_CRON_SESSION=1 env var is replaced with a per-session _CRON_SESSION ContextVar that is scoped to each cron job's try/finally lifecycle.

Root cause: cron/scheduler.py set os.environ["HERMES_CRON_SESSION"] = "1" at the start of every job but never restored it. The gateway runs the cron ticker in-process as a thread, so after the first cron tick, all subsequent gateway sessions inherited the cron marker. With approvals.cron_mode: deny, gateway dangerous commands were silently blocked; with approve, they ran without the expected user approval prompt.

Changes

  • gateway/session_context.py: Added _CRON_SESSION ContextVar (tri-state: _UNSET = legacy env fallback, "1" = cron, "" = explicit non-cron). set_session_vars() accepts cron_session param; clear_session_vars() resets it.
  • cron/scheduler.py: Replaced os.environ["HERMES_CRON_SESSION"] = "1" with _cron_session_var.set("1") inside the job's try/finally, with token reset in cleanup.
  • gateway/run.py, gateway/platforms/api_server.py, acp_adapter/server.py, tui_gateway/server.py: All gateway entry points pass cron_session="" to explicitly mark non-cron sessions, masking any stale process env.
  • tools/approval.py: _is_cron_approval_context() reads the ContextVar via get_session_env() (with env fallback for CLI/tests). All four env_var_enabled("HERMES_CRON_SESSION") callsites replaced.
  • Tests: E2E isolation test, session_env tristate tests, conftest fixture for ContextVar reset.

Validation

Before After
Cron tick leaks to gateway Yes (process env persists) No (ContextVar scoped)
Gateway approvals after cron tick Misrouted (deny/approve wrong) Correct (gateway session wins)
Legacy CLI cron fallback N/A Preserved (_UNSET falls back to env)
Tests 0 isolation tests 26 new/updated tests pass

Salvaged from PR #43370 by @hinablue (the most thorough of 4 competing PRs). Also closes #37969, #43549.

Co-authored-by: hinablue hinablue@gmail.com
Closes #37968

Replace the process-global HERMES_CRON_SESSION env var with a per-session
ContextVar so a cron tick in the gateway process cannot leak into unrelated
live gateway/API/TUI turns. The cron scheduler now sets the ContextVar
inside the job's try/finally scope and resets it on cleanup. Gateway, API
server, ACP adapter, and TUI gateway all pass cron_session='' to explicitly
mark their sessions as non-cron, masking any stale process env.

Co-authored-by: hinablue <hinablue@gmail.com>
Closes NousResearch#37968
@kshitijk4poor
kshitijk4poor force-pushed the fix/cron-session-isolation branch from d10361d to d9fb24d Compare August 2, 2026 18:50
@kshitijk4poor
kshitijk4poor merged commit fb6446f into NousResearch:main Aug 2, 2026
35 checks passed
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery comp/acp Agent Communication Protocol adapter comp/tui Terminal UI (ui-tui/ + tui_gateway/) comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint area/auth Authentication, OAuth, credential pools area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data needs-decision Awaiting maintainer decision before any implementation labels Aug 2, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: #58663 is the earlier ContextVar repair for the same cron-marker leak. This patch additionally clears non-cron entry-point context and env-snapshot exposure; maintainer decision needed on the preferred scope.

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

Labels

area/auth Authentication, OAuth, credential pools area/sessions Session lifecycle, resume, persistence, history comp/acp Agent Communication Protocol adapter comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cron Cron scheduler and job management comp/gateway Gateway runner, session dispatch, delivery comp/tui Terminal UI (ui-tui/ + tui_gateway/) needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists 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/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(cron): isolate gateway approvals from environment pollution

2 participants