Repository navigation
fix(profiles): merge distributed cron jobs without replacing runtime state - #120910
Closed
JoaoMarcos44 wants to merge 2 commits into
Closed
JoaoMarcos44 wants to merge 2 commits into
JoaoMarcos44 wants to merge 2 commits into
Conversation
JoaoMarcos44
marked this pull request as ready for review
September 24, 2026 02:09
JoaoMarcos44
force-pushed
the
fix/profile-cron-store-120823
branch
from
September 24, 2026 02:24
6f3914b to
b8b50f7
Compare
|
Thanks @JoaoMarcos44 — this PR is the base of the salvage. Your two commits are carried as-is with your authorship in #121264:
On top of them the stack adds:
Tests: Merged as |
12 of 19 tasks
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.
Summary
Fixes #120823.
Profile distributions currently treat
cron/like a directory of independent authored files, but Hermes cron has one canonical multi-record store:cron/jobs.json. Replacing that file on install/update replaces the installing profile's scheduler state wholesale:profile update;cron/can be copied as if they were authored distribution content.This patch makes the ownership boundary explicit and small:
Root cause
hermes_cli/profile_distribution.py::_merge_dircurrently treats every file under a distribution-owned directory as an independent replaceable root.That assumption works for skill directories, but not for cron:
cron/jobs.jsonis the shared store for all jobs in the profile. Wholesale replacement therefore crosses record ownership boundaries.The same generic directory merge also has no distinction between authored skills and root-level hidden skill bookkeeping such as
.hub,.usage.json, curator state, manifests, locks, and archives.Fix
Canonical cron ownership
cron/jobs.jsonis the only distributable entry undercron/.Job-by-job merge
The shipped store is read through the real
cron.jobsloader, then merged by stable job id. Cron itself owns the authored-field schema viaJOB_DEFINITION_FIELDS, so profile-distribution code does not duplicate the job record contract:times) comes from the author while local progress (completed) survives;next_run_at=None;next_run_atis re-anchored through cron's existing schedule-update logic instead of carrying an instant derived from the old schedule.The merge uses the cron store's own lock and save path rather than writing
jobs.jsondirectly.Skills runtime boundary
At the root of
skills/, hidden entries are Hermes bookkeeping and remain local. Hidden files inside an authored skill directory are still copied, so the rule does not alter skill package contents.Why this is intentionally structural
#120824 addresses the same issue and enumerates the current runtime files under
cron/andskills/.This alternative avoids a list that can become stale when the scheduler gains another DB, lock, ledger, output directory, or sidecar. The ownership rule follows the actual runtime architecture: the cron distribution surface is the job store, not the scheduler's working directory.
Regression coverage
tests/hermes_cli/test_profile_distribution.pynow uses the real cron store rather than the old loosecron/*.jsonfixture model.Coverage pins:
Install safety
Update preservation
Allowlist parity
cron/jobs.jsonpath can be explicitly allowlisted.Scope
Files changed:
cron/jobs.pyhermes_cli/profile_distribution.pytests/hermes_cli/test_profile_distribution.pywebsite/docs/user-guide/profile-distributions.mdNo scheduler execution logic, database schema, delivery behavior, or CLI syntax changes.
Verification
Built from current upstream
mainat068db016fbfb3e9b44169de154781908f91bceae.No local checkout/worktree was used. At head
b8b50f7521e10bbb6b66b1931965ce3383faeb90, GitHub createdCI,Nix flake check, andDocker Build, Test, and Publish, but all three concludedaction_requiredbefore creating any jobs (0 jobs). No remote test suite has executed yet, so this PR does not claim green CI.Infographic