Auto-Discovered Files and the Priority Chain

+15 Mana ✨

Introduction

Auto-discovery is what makes context injection effortless for the common case. Drop the right file in the right place, and Hermes finds it. There is a priority chain so two files do not fight, and a walking strategy that handles both monorepos and nested projects.

Key Concepts

  • Priority chain: Hermes loads at most one project context file per session, picking the first match in a documented order.
  • Auto-discovery roots: The working directory plus its ancestors (up to a few parents) are scanned.
  • Progressive subdirectory discovery: Additional files in subdirectories load on first access during the session.
  • SOUL.md: Loaded independently from HERMES_HOME, never from the working directory.

Real World Context

A developer maintains both their own Hermes-flavored project (with a .hermes.md) and a contributor's branch of a Claude Code project (with a CLAUDE.md). When they cd into either repo and run hermes, the correct context file is picked up. They never have to remember which flavor is in this repo; the priority chain handles it.

Deep Dive

The full priority chain at session start (first match wins among project context types):

text
1. .hermes.md or HERMES.md   ← highest priority (Hermes-native)
2. AGENTS.md                  ← agent-tool-standard
3. CLAUDE.md                  ← Claude Code compatibility
4. .cursorrules               ← Cursor IDE fallback

Alongside this, two other files load independently rather than competing for the slot:

  • SOUL.md: Loaded from HERMES_HOME/SOUL.md (typically ~/.hermes/SOUL.md). It carries personality and tone, not project rules. It is intentionally restricted to HERMES_HOME so a working-directory file cannot impersonate the agent's personality.
  • USER.md and MEMORY.md: Loaded from ~/.hermes/memories/ as part of the memory subsystem.

The walker for the priority-chain files starts at the current working directory and checks upward through parent directories (typically up to five levels) until it finds a match or hits a stopping condition like the git root. This means a context file at the top of a monorepo is found from any subdirectory inside it.

Progressive subdirectory discovery is the second half of the system. As the agent accesses files in subdirectories (read_file, terminal, search_files), Hermes checks those subdirectories for their own context files (e.g., frontend/AGENTS.md, backend/AGENTS.md) and injects them just-in-time. Each subdirectory is checked at most once per session, so the cost is bounded.

A practical limit: each loaded context file is capped at ~20,000 characters with a 70% head + 20% tail truncation rule. Going over that cap is not catastrophic but does mean some of the file will not be in the prompt. The agent can read the file fully via the file tools if needed, but it will not have it on automatic recall.

Common Pitfalls

  1. Stacking redundant files: Putting both AGENTS.md and CLAUDE.md in the same repo wastes effort; only the higher-priority one loads automatically.
  2. Trusting unfamiliar projects: Auto-discovery loads whatever AGENTS.md says into the prompt. For repos you do not control, review the file before launching the agent there.

Best Practices

  1. One project context file per repo: Pick .hermes.md if your team is Hermes-native, otherwise AGENTS.md. Avoid duplicates.
  2. Use nested files for monorepo subsystems: frontend/AGENTS.md and backend/AGENTS.md keep root-level context lean and load just-in-time when relevant.

Summary

  • Hermes loads at most one project context file at startup, picked by priority: .hermes.md then AGENTS.md then CLAUDE.md then .cursorrules.
  • SOUL.md and persistent memory files load independently from HERMES_HOME and ~/.hermes/memories/.
  • Progressive subdirectory discovery adds nested context just-in-time, capped per subdirectory.
  • Each file is capped at ~20K chars with head+tail truncation if oversized.

Code Examples

text
my-monorepo/
├── AGENTS.md             # loaded at startup (top of priority chain)
├── frontend/
│   └── AGENTS.md         # loaded the first time the agent reads anything in frontend/
├── backend/
│   └── AGENTS.md         # loaded the first time the agent reads anything in backend/
└── shared/
    └── AGENTS.md         # loaded when shared/ is first accessed

# Root context stays lean; subsystem-specific rules load when relevant.
✓ Completed