Skip to content

fix(cron): run scripts from job workdir - #57415

Draft
ayahohner1 wants to merge 1 commit into
NousResearch:mainfrom
ayahohner:fix/cron-script-workdir
Draft

fix(cron): run scripts from job workdir#57415
ayahohner1 wants to merge 1 commit into
NousResearch:mainfrom
ayahohner:fix/cron-script-workdir

Conversation

@ayahohner1

@ayahohner1 ayahohner1 commented Jul 3, 2026

Copy link
Copy Markdown

What does this PR do?

Run cron script subprocesses from the job's configured workdir when one is present, while preserving the existing default of running scripts from HERMES_HOME/scripts when no workdir is configured.

Why this approach: the script path should still be resolved and contained under HERMES_HOME/scripts for safety, but the subprocess cwd should match the cron job's documented project workdir. Threading an explicit cwd into _run_job_script() fixes the bug without relying on process-global os.chdir().

Related Issue

Fixes #21721

Related existing PRs: #21397 and #42920. This PR is intentionally draft because it overlaps with existing contributor work; maintainers can close this if one of those should land instead.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • cron/scheduler.py
    • Add optional cwd parameter to _run_job_script().
    • Use that cwd for subprocess.run(...) when provided.
    • Resolve the job script cwd from job["workdir"].
    • Pass the job workdir to both no-agent scripts and agent pre-run scripts.
  • tests/cron/test_cron_no_agent.py
    • Add regression coverage proving no-agent scripts can read project-relative files from workdir.
  • tests/cron/test_scheduler.py
    • Add regression coverage proving agent pre-run scripts receive the configured workdir.

How to Test

  1. Run the no-agent cron tests:

    python -m pytest tests/cron/test_cron_no_agent.py -q -o 'addopts='

    Expected: 19 passed

  2. Run the targeted scheduler + no-agent cron tests:

    python -m pytest tests/cron/test_scheduler.py tests/cron/test_cron_no_agent.py -q -o 'addopts='

    Expected: 227 passed

  3. Run lint on changed files:

    ruff check cron/scheduler.py tests/cron/test_cron_no_agent.py tests/cron/test_scheduler.py

    Expected: No issues found

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Ubuntu 24.04 / Linux 6.8.0-101-generic

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

N/A

Screenshots / Logs

Pytest: 19 passed
Pytest: 227 passed
Ruff: No issues found
git diff --check: clean

@alt-glitch alt-glitch added type/bug Something isn't working comp/cron Cron scheduler and job management P3 Low — cosmetic, nice to have duplicate This issue or pull request already exists labels Jul 3, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #21397 (earliest open PR) — both thread the configured cron job workdir into _run_job_script()'s subprocess cwd, overriding the hardcoded cwd=path.parent. Same function, same mechanism. Related to the no_agent-specific siblings #42274 / #56005 and the origin bug #21721. You flagged this yourself as a draft to avoid competing; keeping #21397 as canonical for the general fix.

@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 the focused cron fix. The underlying issue is still present: current main hardcodes the script subprocess cwd at cron/scheduler.py:2106, and the agent pre-run path reaches it through cron/scheduler.py:2758.

Problems

  • Current main added _run_job_script_with_claim_heartbeat() in cd537187611769ebb6a1aa9460265e9ef5694606; both no-agent and pre-run scripts now use it (cron/scheduler.py:2611, 2758). The salvage must thread the cwd through that wrapper rather than replacing those calls with direct _run_job_script() calls, or one-shot scripts lose their claim-refresh protection.
  • Runtime workdir validation currently happens at cron/scheduler.py:2868-2876, after the pre-run script. Resolve and validate the cwd before both script paths so a removed workdir retains the existing script-directory fallback.
  • The agent regression test mocks _run_job_script, but production now calls the heartbeat wrapper. Update it to assert the current integration path and retain real-subprocess coverage for both modes.

Suggested changes

  • Pass a validated optional cwd through _run_job_script_with_claim_heartbeat() to _run_job_script() and remove the no-agent os.chdir() path.
  • Add a claimed one-shot regression test to ensure the heartbeat wrapper remains active.

Automated hermes-sweeper review.

Comment thread cron/scheduler.py
@@ -2288,23 +2304,7 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:
# Apply workdir if configured — lets scripts use predictable relative

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.

Current main now routes no-agent scripts through _run_job_script_with_claim_heartbeat() to keep one-shot claims alive (cd5371876). During salvage, preserve that wrapper and thread cwd through it; replacing the call with direct _run_job_script() would drop the duplicate-dispatch protection.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
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 duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: cron job workdir ignored for pre-run script subprocess

4 participants