hermes-agent/tests/cron
Ben b75757d4aa feat(cron): wire on_jobs_changed, cron.chronos config, docs + agent↔NAS contract
Phase 4F (F.1 + F.2 + F.3, agent side). F.4 is the operator-run live smoke
(needs a NAS deployment); recorded in the PR, not code.

F.1 — on_jobs_changed wiring:
- cron/scheduler.py: _notify_provider_jobs_changed() — resolve the active
  provider, call on_jobs_changed(), swallow errors. Lives in scheduler.py (not
  jobs.py) so the store stays free of provider imports (no import cycle).
- Wired at the consumer surfaces AFTER a successful mutation: the cronjob model
  tool (tools/cronjob_tools.py, create/update/remove/pause/resume) — which the
  `hermes cron` CLI also routes through — and the REST handlers
  (gateway/platforms/api_server.py, same five). Built-in's no-op default = zero
  behavior change on the default path. Sleeping-agent direct jobs.json writes
  (no tool/CLI/REST) are covered by reconcile-on-wake in start().

F.2 — config: cron.chronos.{portal_url,callback_url,expected_audience,
nas_jwks_url}. All non-secret; the agent holds no scheduler creds and the
outbound provision call reuses the existing Nous token (no token key). Additive
deep-merge key, no version literal.

F.3 — docs:
- docs/chronos-managed-cron-contract.md: authoritative agent↔NAS wire contract
  (the three agent-cron endpoints + inbound /api/cron/fire + the 3-hop trust
  model + at-most-once/re-arm semantics). This is what the NAS-side agent builds
  against.
- cron-internals.md: "Managed cron (Chronos) for scale-to-zero" section.
- cli-commands.md: cron.provider accepts chronos + the cron.chronos.* keys.
- User docs name no scheduler vendor (QStash is a NAS-internal detail).

INVARIANT re-verified: zero qstash/upstash hits across plugins/cron, gateway,
hermes_cli, tools, website/docs (the one remaining repo hit is an unrelated
Context7 MCP comment in tools/mcp_tool.py).

Tests: test_jobs_changed_notify (5) — notify calls provider hook, swallows
errors, built-in harmless, tool create/remove notify. Full cron + chronos +
webhook + config + api_server_jobs suites green (504 in the cron+chronos+webhook
run).
2026-06-18 15:11:32 +10:00
..
__init__.py test: add unit tests for 8 modules (batch 2) 2026-02-26 13:54:20 +03:00
test_blueprint_catalog.py docs: finish Automation Blueprints terminology rebrand (#44470) 2026-06-11 17:22:22 -04:00
test_claim_job_for_fire.py feat(cron): store-level CAS claim for multi-machine at-most-once fire 2026-06-18 14:34:34 +10:00
test_codex_execution_paths.py refactor(session-log): delete _save_session_log and all callers 2026-05-20 11:44:10 -07:00
test_compute_next_run_last_run_at.py fix(cron): use last_run_at as croniter base for cron jobs 2026-04-29 08:24:48 -07:00
test_cron_context_from.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_cron_inactivity_timeout.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_cron_no_agent.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_cron_prompt_injection_skill.py fix(cron): don't strict-scan script-injected output in no-skills jobs (#43223) 2026-06-10 08:27:24 +05:30
test_cron_script.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_cron_workdir.py fix(cron): make sequential jobs non-blocking too + sweep MCP after jobs finish 2026-06-04 05:40:13 -07:00
test_cronjob_schema.py test(cron): guard schedule-required description text on CRONJOB_SCHEMA 2026-05-26 14:09:37 -07:00
test_file_permissions.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_jobs.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_jobs_changed_notify.py feat(cron): wire on_jobs_changed, cron.chronos config, docs + agent↔NAS contract 2026-06-18 15:11:32 +10:00
test_jobs_crossprocess_lock.py fix: complete cron jobs lock salvage 2026-06-15 06:29:00 -07:00
test_parallel_pool.py revert(cron): remove per-job profile support (PR #28124) (#43956) 2026-06-10 20:46:17 -07:00
test_rewrite_skill_refs.py fix(curator): rewrite cron job skill refs after consolidation (#18253) 2026-04-30 23:04:50 -07:00
test_run_one_job.py refactor(cron): extract run_one_job shared firing helper from tick 2026-06-18 14:26:29 +10:00
test_scheduler.py Merge remote-tracking branch 'origin/main' into hermes/hermes-6b48295e 2026-06-11 07:38:25 -07:00
test_scheduler_mcp_init.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
test_scheduler_provider.py feat(cron): additive CronScheduler hooks (on_jobs_changed/fire_due/reconcile) 2026-06-18 14:30:31 +10:00
test_suggestions.py refactor(cron): rebrand Cron Recipes -> Automation Blueprints 2026-06-11 10:49:47 -07:00