hermes - ✅(Solved) Fix [Bug]: Hermes injects unrelated AGENTS.md/CLAUDE.md/.cursorrules into agent context via tool-path discovery [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#14471Fetched 2026-04-24 06:17:00
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×3cross-referenced ×2commented ×1referenced ×1

Error Message

Additional Logs / Traceback (optional)

Root Cause

An agent should not silently ingest instructions from unrelated directories just because: a tool touched some file elsewhere on disk a terminal command contained a path-like token an ancestor directory outside the workspace happened to contain AGENT.md i

Fix Action

Fixed

PR fix notes

PR #14510: fix(agent): scope subdirectory hint discovery to workspace - closes #14471

Description (problem / solution / changelog)

Fix: Scope subdirectory hint discovery to workspace directory

Bug

Closes #14471

Hermes has a second project-context injection path beyond the normal startup cwd-based prompt assembly. Post-tool-call path discovery can append context from nearby AGENTS.md, CLAUDE.md, or .cursorrules files based on tool arguments — even from directories completely outside the intended workspace.

This breaks workspace isolation expectations and can cause:

  • Unexpected instruction contamination
  • Profile/agent behavior drift
  • Hard-to-debug prompt pollution
  • Cross-project leakage of local instruction files

Root Cause

In agent/subdirectory_hints.py, SubdirectoryHintTracker._is_valid_subdir() only checks:

  1. Is the path a directory?
  2. Has it already been loaded?

It does not check whether the directory is inside the configured working_dir. This means any tool call that touches a file in an unrelated directory can trigger hint discovery there.

Fix

Add a workspace boundary check in _is_valid_subdir() using Path.relative_to(). Only directories inside working_dir are scanned for hint files:

def _is_valid_subdir(self, path: Path) -> bool:
    # ... existing checks ...
    # Scope to workspace — only scan directories inside working_dir
    try:
        path.relative_to(self.working_dir)
    except ValueError:
        logger.debug(
            "Skipping subdirectory hint for %s: outside working_dir %s",
            path, self.working_dir,
        )
        return False
    return True

Impact

  • Prevents injection of unrelated AGENTS.md/CLAUDE.md/.cursorrules from outside the workspace
  • Minimal change (15 lines added, 1 line modified)
  • No behavioral change for directories inside the workspace
  • Debug logging when a directory is skipped (for troubleshooting)

Changed files

  • agent/subdirectory_hints.py (modified, +15/-1)

PR #14795: fix(agent): scope subdirectory hint discovery to active workspace boundary

Description (problem / solution / changelog)

What does this PR do?

Post-tool-call path discovery scanned any directory for AGENTS.md, CLAUDE.md, and .cursorrules files, even those outside the intended workspace. A tool call touching a file elsewhere on disk could silently inject unrelated instruction files into the agent context, causing unexpected behavior drift and cross-project leakage.

Related Issue

Fixes #14471

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • 🔒 Security fix

Changes Made

  • agent/subdirectory_hints.py: Scoped discovery to active workspace boundary
  • tests/agent/test_subdirectory_hints.py: 26 tests

How to Test

python -m pytest -o 'addopts=' tests/agent/test_subdirectory_hints.py -v

Result: 26 passed.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs
  • My PR contains only changes related to this fix
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes
  • I've tested on my platform: macOS 15 (Darwin 24.6.0), Python 3.14.2

Documentation & Housekeeping

  • N/A for all documentation items

Changed files

  • agent/subdirectory_hints.py (modified, +40/-6)
  • tests/agent/test_subdirectory_hints.py (modified, +93/-12)

Code Example

Report     https://paste.rs/x40Qu
agent.log  https://paste.rs/0pl92

---
RAW_BUFFERClick to expand / collapse

Bug Description

Hermes has a second project-context injection path beyond the normal startup cwd-based prompt assembly.

Even when the initial session context is clean, post-tool-call path discovery can append context from nearby AGENTS.md, CLAUDE.md, or .cursorrules files based on tool arguments. This can pull in unrelated instruction files from outside the intended workspace and contaminate the agent’s context.

This is especially problematic for long-running orchestrator agents , where an unrelated AGENTS.md can silently influence behavior mid-session.

Why this is a bug This breaks workspace isolation expectations. In my case, it pulls in the AGENTS.md inside the "hermes-agent" runtime folder.

An agent should not silently ingest instructions from unrelated directories just because: a tool touched some file elsewhere on disk a terminal command contained a path-like token an ancestor directory outside the workspace happened to contain AGENT.md i

This can cause: unexpected instruction contamination profile/agent behavior drift hard-to-debug prompt pollution cross-project leakage of local instruction files

Recommended behavior Only load post-tool-call subdirectory hints when the discovered directory is: inside the configured working_dir, or inside the active repo root associated with that workspace

Additional note Messaging/gateway sessions may be more exposed if TERMINAL_CWD is broad or falls back unexpectedly, since that increases the chance of incorrect workspace assumptions. But the primary bug is the permissive external-path scanning in agent/subdirectory_hints.py.

Steps to Reproduce

Start Hermes in workspace A with no problematic local AGENTS.md Make a tool call that touches a file in unrelated directory B Put an AGENTS.md in B or one of its ancestors Hermes appends: [Subdirectory context discovered: ...] Agent behavior is now influenced by unrelated instructions from directory B(2/3) Proposed fix Scope subdirectory hint discovery to the active workspace only.

Expected Behavior

Project context discovery should be limited to the active workspace/repo for the session.

A tool call that touches a file outside the intended workspace should not cause Hermes to ingest unrelated AGENTS.md/CLAUDE.md/.cursorrules files from ancestor directories elsewhere on disk.

Actual Behavior

After tool calls, Hermes inspects tool arguments for paths and scans those paths plus ancestors for:

AGENTS.md CLAUDE.md .cursorrules

If found, it appends the contents to the tool result as:

[Subdirectory context discovered: ...]

This happens even for paths outside the active working directory.

Affected Component

Tools (terminal, file ops, web, code execution, etc.)

Messaging Platform (if gateway-related)

No response

Debug Report

Report     https://paste.rs/x40Qu
agent.log  https://paste.rs/0pl92

Operating System

Pop!_OS 24.04 LTS

Python Version

No response

Hermes Version

No response

Additional Logs / Traceback (optional)

Root Cause Analysis (optional)

There are two separate context-loading mechanisms:

Startup context loading agent/prompt_builder.py

This is relatively constrained: .hermes.md via walk-to-git-root AGENTS.md, CLAUDE.md, .cursorrules from cwd only

Relevant code: agent/prompt_builder.py:1019-1045 agent/prompt_builder.py:957-1016

Post-tool-call subdirectory hint loading agent/subdirectory_hints.py

This is much more permissive: extracts path-like values from tool args (path, file_path, workdir) parses terminal commands for path-like tokens (1/3) walks ancestor directories loads the first matching hint file appends it into the conversation

Relevant code: run_agent.py:1749-1751 — tracker initialization run_agent.py:7846-7848 — append hints after one tool path run_agent.py:8205-8208 — append hints after another tool path agent/subdirectory_hints.py:29-33 — hint filenames agent/subdirectory_hints.py:38-46 — tracked arg keys and ancestor walk agent/subdirectory_hints.py:67-89 — check_tool_call agent/subdirectory_hints.py:97-109 — direct path extraction agent/subdirectory_hints.py:141-158 — terminal command path extraction agent/subdirectory_hints.py:171-224 — hint loading and injection format

Evidence that external paths are intentionally allowed There is already a test that explicitly confirms this behavior:

tests/agent/test_subdirectory_hints.py:125-135 test: test_outside_working_dir_still_checked

That test asserts that a path outside working_dir is still checked and can load AGENTS.md.

So this is not incidental behavior, it is currently baked into the implementation and tests.

Proposed Fix (optional)

Constrain candidate directories in: agent/subdirectory_hints.py _add_path_candidate() and/or _is_valid_subdir()

Suggested config addition Add a config mode, something like:

agent.subdirectory_hints_mode: workspace

Possible values: disabled workspace external

Recommended default: workspace

That preserves the feature while preventing unrelated context injection by default.

Are you willing to submit a PR for this?

  • I'd like to fix this myself and submit a PR

extent analysis

TL;DR

Constrain the subdirectory hint discovery in agent/subdirectory_hints.py to only consider directories within the active workspace or configured working directory.

Guidance

  • Review the agent/subdirectory_hints.py file, specifically the _add_path_candidate() and _is_valid_subdir() functions, to understand how external paths are currently being handled.
  • Consider adding a configuration option, such as agent.subdirectory_hints_mode, to control the behavior of subdirectory hint discovery, with possible values including disabled, workspace, and external.
  • Update the agent/subdirectory_hints.py file to respect the new configuration option and only load hints from directories within the active workspace or configured working directory.
  • Verify that the changes do not introduce any regressions by running the existing tests, including tests/agent/test_subdirectory_hints.py.

Example

# agent/subdirectory_hints.py
def _add_path_candidate(path):
    # Check if the path is within the active workspace or configured working directory
    if not is_path_within_workspace(path):
        return
    # ... rest of the function remains the same

def is_path_within_workspace(path):
    # Implement logic to check if the path is within the active workspace or configured working directory
    # This may involve checking the path against the `working_dir` configuration option
    pass

Notes

The proposed fix requires careful consideration of the trade-offs between feature functionality and security. The changes should be thoroughly tested to ensure that they do not introduce any regressions or unintended behavior.

Recommendation

Apply the proposed workaround by constraining the subdirectory hint discovery to the active workspace or configured working directory, as this will prevent unrelated context injection and improve the security of the system.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING