Skip to content

fix(cron): scope cron job workdir to own session instead of process-global cwd (#69396) - #70915

Closed
kshitijk4poor wants to merge 4 commits into
NousResearch:mainfrom
kshitijk4poor:review/70548-cron-workdir-scope
Closed

kshitijk4poor wants to merge 4 commits into
NousResearch:mainfrom
kshitijk4poor:review/70548-cron-workdir-scope

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Contributor

Summary

Cron job workdir no longer leaks into concurrent gateway sessions — the per-context _SESSION_CWD ContextVar is set via set_session_vars(cwd=...) instead of process-global os.chdir().

Previously, a cron job with workdir set mutated the process-global cwd (os.chdir() in no_agent path, TERMINAL_CWD env var in agent path). Any gateway session created while the cron was running inherited that cwd and loaded the wrong AGENTS.md, causing the gateway session to execute the cron's task instead of the user's request. Fixes #69396.

Changes

  • cron/scheduler.py:
    • no_agent path: replaces os.chdir() with subprocess.run(cwd=workdir) — process cwd is never mutated
    • agent path: passes cwd=_job_workdir to set_session_vars(), letting the existing session-context machinery handle _SESSION_CWD set/clear (no separate import/set/clear dance)
    • removed redundant clear_session_cwd() block — clear_session_vars() already calls it internally
    • error path now includes exception message in output
  • tests/cron/test_scheduler.py: updated test stub to accept new workdir kwarg

Validation

Before After
Cron workdir leak to gateway Yes (race) No (ContextVar scoped)
os.chdir() in no_agent path Yes No (subprocess cwd=)
test_scheduler.py 239 pass 239 pass
E2E thread isolation N/A Confirmed

Cherry-picked from #70548 by @webtecnica. Simplified to use existing set_session_vars(cwd=) instead of separate set/clear. First commit (#68915 spawn rewrite) already on main as d7512c8 — only the cron workdir fix is salvaged here.

Hermes Agent and others added 4 commits July 24, 2026 23:06
NousResearch#69396)

The cron scheduler was mutating process-global state in two places:
1. no_agent path called os.chdir() which changed the global process cwd,
   leaking into concurrent gateway sessions.
2. The agent path set os.environ['TERMINAL_CWD'] which any gateway
   session could read during context-file discovery via
   resolve_context_cwd/build_context_files_prompt.

Fix:
- no_agent path: pass workdir as subprocess cwd parameter to
  _run_job_script() instead of os.chdir(). The Python process cwd
  is never mutated.
- Agent path: in addition to the lock-serialized TERMINAL_CWD,
  also set the per-context _SESSION_CWD ContextVar from
  agent.runtime_cwd. This ContextVar is scoped to the current
  thread/context and NEVER leaks into other sessions.
  resolve_context_cwd() checks _SESSION_CWD first, so the cron's
  own context file discovery uses the correct workdir, while
  gateway sessions (which have no override) fall through to their
  own TERMINAL_CWD.
Eliminates the separate import/set/clear dance for _SESSION_CWD by
passing cwd= directly to set_session_vars(), which already handles
the ContextVar set internally and clears it via clear_session_vars().
Also includes the exception message in the no_agent error path.

Follow-up to salvaged PR NousResearch#70548 (NousResearch#69396).
Follow-up to salvaged PR NousResearch#70548 — _run_job_script now accepts
workdir= kwarg, test mocks need to accept it too.
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/cron Cron scheduler and job management sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 24, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Merged via #70989 byte-identical — your salvage of webtecnica's fix (authorship preserved via the agent@hermes.dev mapping) reusing set_session_vars(cwd=) was exactly right. Fixes #69396.

@teknium1 teknium1 closed this Jul 24, 2026
@kshitijk4poor
kshitijk4poor deleted the review/70548-cron-workdir-scope branch August 5, 2026 07:09
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 P1 High — major feature broken, no workaround 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.

[Bug]: cron job workdir is applied as global process cwd and leaks into gateway sessions created during the run

3 participants