{"repo":"NousResearch/hermes-agent","public_id":"5200","display_label":"SOUL.md and AGENTS.md identity loading fixes","summary":"A cluster of bugs, fixes, and docs updates centered on SOUL.md and AGENTS.md not being loaded or honored as agent identity across gateway, cron, TUI, and bot contexts. Work includes path resolution, config wiring, caching, and documentation corrections.","subsystem":"agent","counts":{"members":28,"open_issues":3,"open_issues_distinct":3,"open_prs":3,"closed_issues":10,"merged_prs":1,"attempt_prs":14},"landed_fix":{"status":"merged_to_main","basis":"structural","pr":17509},"resolution":{"state":"partially_resolved","by":"pr-17509"},"freshness":{"state":"verified","last_verified_at":"2026-04-29T15:10:25+00:00","is_stale":false},"grouping":{"backbone":"STRUCTURAL_PARTIAL","link_density":0.05968253968253965},"fix_edges":[{"issue_number":16756,"pr_number":17509,"tier":"verified","basis":"closing_ref","confidence":0.95,"recoverable_from_timeline":true}],"members":[{"kind":"issue","number":5200,"title":"[docs] Context Files (AGENTS.md/SOUL.md): documented behavior doesn't match code","url":null,"state":"closed"},{"kind":"issue","number":6731,"title":"Feishu bot uses hardcoded DEFAULT_AGENT_IDENTITY instead of SOUL.md for system prompt","url":null,"state":"closed"},{"kind":"issue","number":11763,"title":"AGENTS.md not loaded in gateway mode (WeChat/Telegram/Discord) — inconsistent agent behavior across platforms","url":null,"state":"open"},{"kind":"issue","number":16756,"title":"[Bug]: CRON tasks do not apply prompts defined in SOUL.md","url":null,"state":"closed"},{"kind":"issue","number":26596,"title":"[Bug] Gateway mode ignores SOUL.md and agent.personalities — DEFAULT_AGENT_IDENTITY always used","url":null,"state":"closed"},{"kind":"issue","number":29476,"title":"[Setup]: USER.md seems to be unknown to hermes","url":null,"state":"closed"},{"kind":"issue","number":32843,"title":"[Bug]: SOUL.md and AGENTS.md not loaded for Telegram gateway sessions in v0.14.0","url":null,"state":"closed"},{"kind":"issue","number":34852,"title":"SOUL.md/personality not reflected in hermes -z oneshot identity","url":null,"state":"closed"},{"kind":"issue","number":37480,"title":"Gateway (Telegram) ignores custom SOUL.md + AGENTS.md — serves DEFAULT_AGENT_IDENTITY despite correct paths, default profile, and load_soul_identity=true","url":null,"state":"closed"},{"kind":"issue","number":43910,"title":"[Bug]: SOUL.md not loaded as agent identity in Desktop TUI mode — persona system overrides it silently","url":null,"state":"closed"},{"kind":"issue","number":66118,"title":"[Bug]: Profile SOUL.md / AGENTS.md identity ignored with custom Ollama provider (v0.18.2)","url":null,"state":"open"},{"kind":"issue","number":66394,"title":"SOUL.md Not Loading in Telegram Gateway","url":null,"state":"closed"},{"kind":"issue","number":66396,"title":"SOUL.md Not Loading in Telegram Gateway","url":null,"state":"open"},{"kind":"pr","number":6761,"title":"fix(gateway): evict cached agents across fresh session boundaries","url":null,"state":"closed","close_reason":{"category":"silent_close","implication":"active"},"merged":false},{"kind":"pr","number":11885,"title":"fix(prompt): load AGENTS.md from HERMES_HOME","url":null,"state":"open","close_reason":{"refs":[{"kind":"pr","value":"#23412","number":23412}],"category":"uncategorized","implication":"needs_llm"},"merged":false},{"kind":"pr","number":16947,"title":"fix(cron): keep SOUL.md identity without workdir","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#17509","number":17509},{"kind":"pr","value":"#16756","number":16756}],"category":"merged_via","implication":"superseded"},"merged":false},{"kind":"pr","number":17509,"title":"fix(cron): keep SOUL.md identity when workdir is unset (#16756)","url":null,"state":"merged","close_reason":{"category":"merged","implication":"superseded"},"merged":true,"is_fix_pr":true,"fix_tier":"verified","files_changed":["cron/scheduler.py","run_agent.py","scripts/release.py","tests/cron/test_cron_workdir.py","tests/run_agent/test_run_agent.py"],"fix_hunks":[{"file":"cron/scheduler.py","hunks":["@@ -1033,10 +1033,12 @@ def run_job(job: dict) -> tuple[bool, str, str, Optional[str]]:\n             enabled_toolsets=_resolve_cron_enabled_toolsets(job, _cfg),\n             disabled_toolsets=[\"cronjob\", \"messaging\", \"clarify\"],\n             quiet_mode=True,\n-            # When a workdir is configured, inject AGENTS.md / CLAUDE.md /\n-            # .cursorrules from that directory; otherwise preserve the old\n-            # behaviour (don't inject SOUL.md/AGENTS.md from the scheduler cwd).\n+            # Cron jobs should always inherit the user's SOUL.md identity from\n+            # HERMES_HOME. When a workdir is configured, also inject project\n+            # context files (AGENTS.md / CLAUDE.md / .cursorrules) from there.\n+            # Without a workdir, keep cwd context discovery disabled.\n             skip_context_files=not bool(_job_workdir),\n+            load_soul_identity=True,\n             skip_memory=True,  # Cron system prompts would corrupt user representations\n             platform=\"cron\",\n             session_id=_cron_session_id,"]},{"file":"run_agent.py","hunks":["@@ -926,6 +926,7 @@ def __init__(\n         thread_id: str = None,\n         gateway_session_key: str = None,\n         skip_context_files: bool = False,\n+        load_soul_identity: bool = False,\n         skip_memory: bool = False,\n         session_db=None,\n         parent_session_id: str = None,","@@ -977,6 +978,9 @@ def __init__(\n             skip_context_files (bool): If True, skip auto-injection of SOUL.md, AGENTS.md, and .cursorrules\n                 into the system prompt. Use this for batch processing and data generation to avoid\n                 polluting trajectories with user-specific persona or project instructions.\n+            load_soul_identity (bool): If True, still use ~/.hermes/SOUL.md as the primary\n+                identity even when skip_context_files=True. Project context files from the cwd\n+                remain skipped.\n         \"\"\"\n         _install_safe_stdio()\n ","@@ -1005,6 +1009,7 @@ def __init__(\n         self._print_fn = None\n         self.background_review_callback = None  # Optional sync callback for gateway delivery\n         self.skip_context_files = skip_context_files\n+        self.load_soul_identity = load_soul_identity\n         self.pass_session_id = pass_session_id\n         self._credential_pool = [redacted:secret-assignment]\n         self.log_prefix_chars = log_prefix_chars","@@ -4742,9 +4747,11 @@ def _build_system_prompt(self, system_message: str = None) -> str:\n         #   6. Current date & time (frozen at build time)\n         #   7. Platform-specific formatting hint\n \n-        # Try SOUL.md as primary identity (unless context files are skipped)\n+        # Try SOUL.md as primary identity unless the caller explicitly skipped it.\n+        # Some execution modes (cron) still want HERMES_HOME persona while keeping\n+        # cwd project instructions disabled.\n         _soul_loaded = False\n-        if not self.skip_context_files:\n+        if self.load_soul_identity or not self.skip_context_files:\n             _soul_content = load_soul_md()\n             if _soul_content:\n                 prompt_parts = [_soul_content]"]},{"file":"scripts/release.py","hunks":["@@ -67,6 +67,7 @@\n     \"[redacted:email]\": \"BeliefanX\",\n     \"[redacted:email]\": \"Mind-Dragon\",\n     \"[redacted:email]\": \"westers\",\n+    \"[redacted:email]\": \"liuhao1024\",\n     \"[redacted:email]\": \"devorun\",\n     \"[redacted:email]\": \"beesrsj2500\",\n     \"[redacted:email]\": \"beesrsj2500\","]},{"file":"tests/cron/test_cron_workdir.py","hunks":["@@ -265,6 +265,7 @@ def _install_stubs(monkeypatch, observed: dict):\n         class FakeAgent:\n             def __init__(self, **kwargs):\n                 observed[\"skip_context_files\"] = kwargs.get(\"skip_context_files\")\n+                observed[\"load_soul_identity\"] = kwargs.get(\"load_soul_identity\")\n                 observed[\"terminal_cwd_during_init\"] = os.environ.get(\n                     \"TERMINAL_CWD\", \"_UNSET_\"\n                 )","@@ -335,6 +336,7 @@ def test_workdir_sets_and_restores_terminal_cwd(\n \n         # AIAgent was built with skip_context_files=False (feature ON).\n         assert observed[\"skip_context_files\"] is False\n+        assert observed[\"load_soul_identity\"] is True\n         # TERMINAL_CWD was pointing at the job workdir while the agent ran.\n         assert observed[\"terminal_cwd_during_init\"] == str(tmp_path.resolve())\n         assert observed[\"terminal_cwd_during_run\"] == str(tmp_path.resolve())","@@ -373,6 +375,8 @@ def test_no_workdir_leaves_terminal_cwd_untouched(self, monkeypatch):\n \n         # Feature is OFF — skip_context_files stays True.\n         assert observed[\"skip_context_files\"] is True\n+        # Cron still forces SOUL.md identity even when cwd context files stay off.\n+        assert observed[\"load_soul_identity\"] is True\n         # TERMINAL_CWD saw the same value during init as it had before.\n         assert observed[\"terminal_cwd_during_init\"] == before\n         # And after run_job completes, it's still the sentinel (nothing"]},{"file":"tests/run_agent/test_run_agent.py","hunks":["@@ -862,6 +862,26 @@ def test_always_has_identity(self, agent):\n         prompt = agent._build_system_prompt()\n         assert DEFAULT_AGENT_IDENTITY in prompt\n \n+    def test_can_use_soul_identity_even_when_context_files_are_skipped(self):\n+        with (\n+            patch(\"run_agent.get_tool_definitions\", return_value=_make_tool_defs(\"terminal\")),\n+            patch(\"run_agent.check_toolset_requirements\", return_value={}),\n+            patch(\"run_agent.OpenAI\"),\n+            patch(\"run_agent.load_soul_md\", return_value=\"SOUL IDENTITY\"),\n+        ):\n+            agent = AIAgent(\n+                api_key=\"[redacted:secret-assignment]\",\n+                base_url=\"https://openrouter.ai/api/v1\",\n+                quiet_mode=True,\n+                skip_context_files=True,\n+                load_soul_identity=True,\n+                skip_memory=True,\n+            )\n+            prompt = agent._build_system_prompt()\n+\n+        assert \"SOUL IDENTITY\" in prompt\n+        assert DEFAULT_AGENT_IDENTITY not in prompt\n+\n     def test_includes_system_message(self, agent):\n         prompt = agent._build_system_prompt(system_message=\"Custom instruction\")\n         assert \"Custom instruction\" in prompt\n"]}]},{"kind":"pr","number":18878,"title":"fix(agent): load SOUL.md from cwd with fallback to HERMES_HOME","url":null,"state":"closed","close_reason":{"category":"silent_close","implication":"active"},"merged":false},{"kind":"pr","number":23166,"title":"docs(env): mark MESSAGING_CWD as deprecated compatibility fallback","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#22050","number":22050},{"kind":"pr","value":"#34781","number":34781}],"category":"superseded_by_pr","implication":"superseded"},"merged":false},{"kind":"pr","number":23167,"title":"docs(worktrees): use terminal.cwd for gateway working directories","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"119390a2a1eeb47a9b59d29e4158cfd31ae63e1f","number":0}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false},{"kind":"pr","number":23168,"title":"docs(config): clarify messaging cwd in cli-config example","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"119390a2a1eeb47a9b59d29e4158cfd31ae63e1f","number":0}],"category":"implemented_elsewhere","implication":"superseded"},"merged":false},{"kind":"pr","number":23169,"title":"docs(security): recommend terminal.cwd for gateway hardening","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"119390a2a1eeb47a9b59d29e4158cfd31ae63e1f","number":0}],"category":"uncategorized","implication":"needs_llm"},"merged":false},{"kind":"pr","number":26789,"title":"fix(gateway): honor SOUL.md and agent.personality in gateway sessions","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#26596","number":26596}],"category":"uncategorized","implication":"needs_llm"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":34863,"title":"Fix oneshot system prompt handling","url":null,"state":"open","close_reason":{"refs":[{"kind":"pr","value":"#34852","number":34852},{"kind":"pr","value":"#34852","number":34852}],"category":"uncategorized","implication":"needs_llm"},"merged":false},{"kind":"pr","number":37520,"title":"fix(gateway): wire agent.load_soul_identity config to gateway AIAgent construction (#37480)","url":null,"state":"closed","close_reason":{"category":"implemented_elsewhere","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true},{"kind":"pr","number":65800,"title":"fix(agent): load gateway AGENTS.md from HERMES_HOME fallback","url":null,"state":"closed","close_reason":{"refs":[{"kind":"commit","value":"d682f320b35a13084371a541a835e1d988c982b8","number":0},{"kind":"commit","value":"c62bcdeaaeeb","number":0},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#76011","number":76011},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#11763","number":11763},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#29871","number":29871},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#29871","number":29871},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#66118","number":66118},{"kind":"pr","value":"#76011","number":76011},{"kind":"pr","value":"#75108","number":75108},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#29871","number":29871},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#11763","number":11763},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#66118","number":66118},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#76011","number":76011},{"kind":"pr","value":"#1","number":1},{"kind":"pr","value":"#1","number":1},{"kind":"pr","value":"#15803","number":15803},{"kind":"pr","value":"#14532","number":14532},{"kind":"pr","value":"#6","number":6},{"kind":"pr","value":"#1","number":1},{"kind":"pr","value":"#9","number":9},{"kind":"pr","value":"#374151","number":374151},{"kind":"pr","value":"#4338","number":4338},{"kind":"pr","value":"#11763","number":11763},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#65800","number":65800}],"category":"partial_fix","implication":"needs_llm"},"merged":false},{"kind":"pr","number":66155,"title":"fix(prompt): load profile AGENTS.md from HERMES_HOME when cwd lacks it","url":null,"state":"open","close_reason":{"refs":[{"kind":"commit","value":"d682f320b35a13084371a541a835e1d988c982b8","number":0},{"kind":"commit","value":"eb946036d905","number":0},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#76011","number":76011},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#29871","number":29871},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#11763","number":11763},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#66118","number":66118},{"kind":"pr","value":"#76011","number":76011},{"kind":"pr","value":"#75108","number":75108},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#66155","number":66155},{"kind":"pr","value":"#65800","number":65800},{"kind":"pr","value":"#11885","number":11885},{"kind":"pr","value":"#29935","number":29935},{"kind":"pr","value":"#30236","number":30236},{"kind":"pr","value":"#76011","number":76011},{"kind":"pr","value":"#374151","number":374151},{"kind":"pr","value":"#11763","number":11763},{"kind":"pr","value":"#66118","number":66118},{"kind":"pr","value":"#66155","number":66155}],"category":"partial_fix","implication":"needs_llm"},"merged":false},{"kind":"pr","number":66426,"title":"fix(agent): load root SOUL.md when profile home has only the seeded default (#66396)","url":null,"state":"closed","close_reason":{"refs":[{"kind":"pr","value":"#66396","number":66396}],"category":"superseded_by_pr","implication":"superseded"},"merged":false,"is_fix_pr":true,"fix_tier":"suggested","fix_detail_withheld":true}],"trust":{"default_tier":"verified","includes_suggested":false}}