fix(cron): use lazy evaluation for cron paths to prevent test isolation bypass#5
Open
liuhao1024 wants to merge 1 commit into
Open
fix(cron): use lazy evaluation for cron paths to prevent test isolation bypass#5liuhao1024 wants to merge 1 commit into
liuhao1024 wants to merge 1 commit into
Conversation
…on bypass
Module-level constants (JOBS_FILE, CRON_DIR, OUTPUT_DIR, TICKER_HEARTBEAT_FILE,
TICKER_SUCCESS_FILE) are frozen at import time. Tests that monkeypatch
HERMES_HOME with a tempdir (via monkeypatch.setenv('HERMES_HOME', tmp_path))
expect these paths to honor the patched value, but the frozen constants defeat
test isolation — tests write to the real ~/.hermes/cron/jobs.json instead of
the test tempdir, creating real cron jobs that fire during production use.
Add lazy accessor functions (_get_cron_dir(), get_jobs_file(), get_output_dir(),
get_ticker_heartbeat_file(), get_ticker_success_file()) that resolve paths
dynamically on every call, matching the pattern used in cron/scheduler.py.
Internal code uses these accessors; the frozen module-level constants are kept
for backward compatibility.
This prevents test-to-production state leakage in tests/cron/ and
tests/hermes_cli/test_console_engine.py (NousResearch#60014).
Related patterns: NousResearch#50681 (hermes_state.py DEFAULT_DB_PATH, same fix approach).
liuhao1024
pushed a commit
that referenced
this pull request
Jul 10, 2026
…check (#5) The sync _session_has_compression_in_flight sat on the message hot path and blocked the event loop twice: under session_store._lock during _ensure_loaded_locked (JSON read) and via db.get_compression_lock_holder (SQLite SELECT). Async-ify the method and offload both sources via asyncio.to_thread; await the call site in _handle_active_session_busy_message.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Module-level constants (
JOBS_FILE,CRON_DIR,OUTPUT_DIR,TICKER_HEARTBEAT_FILE,TICKER_SUCCESS_FILE) incron/jobs.pyare frozen at import time. Tests that isolateHERMES_HOMEviamonkeypatch.setenv("HERMES_HOME", tmp_path)expect these paths to honor the patched value, but the frozen constants defeat test isolation — tests write to the real~/.hermes/cron/jobs.jsoninstead of the test tempdir, creating real cron jobs that fire during production use.This PR adds lazy accessor functions (
_get_cron_dir(),get_jobs_file(),get_output_dir(),get_ticker_heartbeat_file(),get_ticker_success_file()) that resolve paths dynamically on every call, matching the pattern used incron/scheduler.py:_get_hermes_home(). Internal code uses these accessors; the frozen module-level constants are kept for backward compatibility.Related Issue
Fixes NousResearch#60014
Type of Change
Changes Made
cron/jobs.py: Add lazy accessor functions (_get_cron_dir(),get_jobs_file(),get_output_dir(),get_ticker_heartbeat_file(),get_ticker_success_file())cron/jobs.py: Update all internal usages to call lazy accessors instead of using frozen module-level constantscron/jobs.py: Preserve module-level constants for backward compatibilityHow to Test
Before this patch:
~/.hermespopulated):~/.hermes/cron/jobs.jsoncontains a new job namedwwithprompt: "echo hi"andschedule: every 5m(test leaked into production).After this patch:
~/.hermes/cron/jobs.jsonis unchanged — no new jobs appear from the test run. All 115 tests pass.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passtests/cron/test_jobs_changed_notify.py::test_tool_create_notifies_providerandtests/hermes_cli/test_console_engine.py::test_cron_pause_resume_and_run_require_confirmation) now correctly isolate to tempdirs instead of leaking into production. Adding a new test for this would require the test itself to be aware of the test runner's HERMES_HOME environment, which is circular.Documentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/A