fix(cron): scope profile runtime during webhook fire

This commit is contained in:
kshitijk4poor 2026-07-10 11:26:10 +05:30 committed by kshitij
parent ec0227b435
commit f82c71396d
2 changed files with 59 additions and 7 deletions

View file

@ -10399,18 +10399,26 @@ def _fire_cron_job_for_profile(profile: str, job_id: str) -> bool:
"""Run ONE due cron job end-to-end for ``profile`` via the resolved
scheduler provider's ``fire_due`` (store CAS claim + ``run_one_job``).
Uses the same execution-context store routing as ``_call_cron_for_profile``
so the claim and run operate on the right profile's ``jobs.json`` without
mutating paths observed by the desktop ticker. Runs with no live adapters;
delivery falls back to the per-platform send path.
Scope both cron storage and the runtime Hermes home so the job's store,
config, credentials, scripts, skills, and output all belong to the selected
profile. Runs with no live adapters; delivery falls back to the per-platform
send path.
"""
_profile_name, home = _cron_profile_home(profile)
from cron import jobs as cron_jobs
from cron.scheduler_provider import resolve_cron_scheduler
from hermes_constants import (
reset_hermes_home_override,
set_hermes_home_override,
)
with cron_jobs.use_cron_store(home):
provider = resolve_cron_scheduler()
return bool(provider.fire_due(job_id, adapters=None, loop=None))
token = set_hermes_home_override(str(home))
try:
with cron_jobs.use_cron_store(home):
provider = resolve_cron_scheduler()
return bool(provider.fire_due(job_id, adapters=None, loop=None))
finally:
reset_hermes_home_override(token)
@app.post("/api/cron/fire")

View file

@ -64,6 +64,50 @@ def test_call_cron_for_profile_routes_storage_without_mutating_globals(isolated_
assert cron_jobs.OUTPUT_DIR == old_output_dir
def test_fire_cron_job_scopes_store_and_runtime_home_together(
isolated_profiles,
monkeypatch,
):
"""A profile fire must execute and persist under the same profile home."""
from cron import jobs as cron_jobs
from cron import scheduler
from hermes_cli import web_server
from hermes_constants import (
reset_hermes_home_override,
set_hermes_home_override,
)
default_home = isolated_profiles["default"]
worker_home = isolated_profiles["worker_alpha"]
monkeypatch.setattr(scheduler, "_hermes_home", None)
captured = {}
class RecordingProvider:
def fire_due(self, job_id, *, adapters=None, loop=None):
captured["job_id"] = job_id
captured["runtime_home"] = scheduler._get_hermes_home()
captured["jobs_file"] = cron_jobs._current_cron_store().jobs_file
return True
monkeypatch.setattr(
"cron.scheduler_provider.resolve_cron_scheduler",
lambda: RecordingProvider(),
)
outer_token = set_hermes_home_override(default_home)
try:
assert web_server._fire_cron_job_for_profile("worker_alpha", "worker-job") is True
assert captured == {
"job_id": "worker-job",
"runtime_home": worker_home,
"jobs_file": worker_home / "cron" / "jobs.json",
}
assert scheduler._get_hermes_home() == default_home
finally:
reset_hermes_home_override(outer_token)
def test_profile_call_cannot_retarget_ticker_store_mid_write(
isolated_profiles,
monkeypatch,