{"repo":"NousResearch/hermes-agent","public_id":"41966","display_label":"Cron directory ownership on Docker container restart","summary":"The members concern ownership of the `cron/` directory not being restored when a container restarts, including one bug report and two titles describing changes to chown or repair cron ownership at boot. The titles alone do not show whether any change was merged or whether the problem is fixed.","subsystem":null,"counts":{"members":3,"open_issues":0,"open_issues_distinct":0,"open_prs":0,"closed_issues":1,"merged_prs":1,"attempt_prs":1},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":41976,"merged_at":"2026-06-10T05:32:34+00:00"},"resolution":{"state":"resolved","by":"pr-41976"},"freshness":{"state":"verified","last_verified_at":"2026-06-10T05:32:34+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_SPANNING","link_density":0.6666666666666666},"fix_edges":[{"issue_number":41966,"pr_number":41976,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true,"pr_merged_at":"2026-06-10T05:32:34+00:00"}],"members":[{"kind":"issue","number":41966,"title":"[Bug]: `cron/` directory ownership not restored on container restart","url":null,"state":"closed"},{"kind":"pr","number":41976,"title":"Repair cron ownership on container restart","url":null,"state":"merged","close_reason":{"category":"merged"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["docker/stage2-hook.sh","tests/test_docker_home_override_scripts.py"],"fix_hunks":[{"file":"docker/stage2-hook.sh","hunks":["@@ -262,6 +262,14 @@ if [ -d \"$HERMES_HOME/profiles\" ]; then\n     chown -R hermes:hermes \"$HERMES_HOME/profiles\" 2>/dev/null || true\n fi\n \n+# Always reset ownership of $HERMES_HOME/cron on every boot for the same\n+# docker-exec/root-write reason as profiles/. The cron scheduler state\n+# (jobs.json) must stay readable by the unprivileged hermes runtime even\n+# after root-context maintenance commands or scheduler writes.\n+if [ -d \"$HERMES_HOME/cron\" ]; then\n+    chown -R hermes:hermes \"$HERMES_HOME/cron\" 2>/dev/null || true\n+fi\n+\n # Reset ownership of hermes-owned top-level state files on every boot.\n # The targeted data-volume chown above only covers hermes-owned\n # *subdirectories*; loose state files living directly under $HERMES_HOME"]},{"file":"tests/test_docker_home_override_scripts.py","hunks":["@@ -6,6 +6,7 @@\n REPO_ROOT = Path(__file__).resolve().parent.parent\n DASHBOARD_RUN = REPO_ROOT / \"docker\" / \"s6-rc.d\" / \"dashboard\" / \"run\"\n MAIN_WRAPPER = REPO_ROOT / \"docker\" / \"main-wrapper.sh\"\n+STAGE2_HOOK = REPO_ROOT / \"docker\" / \"stage2-hook.sh\"\n \n \n def test_main_wrapper_preserves_docker_workdir() -> None:","@@ -77,3 +78,14 @@ def test_dashboard_run_does_not_derive_insecure_from_bind_host() -> None:\n         assert truthy in text, (\n             f\"HERMES_DASHBOARD_INSECURE should accept truthy value {truthy!r}\"\n         )\n+\n+\n+def test_stage2_hook_repairs_profiles_and_cron_ownership_on_every_boot() -> None:\n+    \"\"\"profiles/ and cron/ must both be reclaimed after root-context writes.\"\"\"\n+    text = STAGE2_HOOK.read_text(encoding=\"utf-8\")\n+\n+    assert 'if [ -d \"$HERMES_HOME/profiles\" ]; then' in text\n+    assert 'chown -R hermes:hermes \"$HERMES_HOME/profiles\" 2>/dev/null || true' in text\n+\n+    assert 'if [ -d \"$HERMES_HOME/cron\" ]; then' in text\n+    assert 'chown -R hermes:hermes \"$HERMES_HOME/cron\" 2>/dev/null || true' in text\n"]}]},{"kind":"pr","number":41981,"title":"fix(docker): unconditionally chown cron/ on container boot","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#41976","number":41976},{"kind":"pr","value":"#41966","number":41966}],"category":"superseded_by_pr","implication":"superseded"},"merged":false}],"trust":{"default_tier":"verified","includes_suggested":false}}