Skip to content

docs: move Hermes overview out of agent context root - #2619

Merged
1 commit merged into
nesquena:masterfrom
Michaelyklam:fix/issue-2595-move-hermes-context
May 20, 2026
Merged

1 commit merged into
nesquena:masterfrom
Michaelyklam:fix/issue-2595-move-hermes-context

Conversation

@Michaelyklam

Copy link
Copy Markdown
Contributor

Thinking Path

  • Hermes Agent gives root HERMES.md / .hermes.md higher project-context priority than AGENTS.md.
  • This repository's root HERMES.md is a long human-facing overview/comparison document, while AGENTS.md is the assistant-facing contributor guidance.
  • The safest repository-side fix is to move the overview into docs/ and keep root free of Hermes context filenames.
  • A small regression test makes the constraint explicit so the root filename does not come back accidentally.

What Changed

  • Moved HERMES.md to docs/why-hermes.md.
  • Updated README references to the new docs path.
  • Added tests/test_agent_context_docs.py to assert root HERMES.md / .hermes.md do not exist and the README links the moved document.
  • Added an Unreleased changelog entry.

Why It Matters

  • Hermes Agent sessions in this repository now load AGENTS.md as the project-specific assistant guidance instead of the long product-positioning document.
  • The human-facing comparison doc remains published and linked from README.
  • Future contributors get a clear test failure if a root Hermes context file would shadow AGENTS.md again.

Verification

  • env -u HERMES_CONFIG_PATH -u HERMES_WEBUI_HOST /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_agent_context_docs.py -q — 2 passed
  • git diff --check

Risks / Follow-ups

  • This is a docs-path move, so external links to root HERMES.md may need updating if any exist outside this repository.
  • No runtime or UI behavior changes.

Closes #2595

Model Used

AI-assisted change with repository inspection, targeted editing, and shell-based test verification.

@Michaelyklam
Michaelyklam force-pushed the fix/issue-2595-move-hermes-context branch from 9a9e6c3 to 471b75d Compare May 20, 2026 06:56
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Summary

Read the PR diff on 471b75d7 plus issue #2595 and the agent-side selection logic in ~/.hermes/hermes-agent/agent/prompt_builder.py. The fix is correct, narrowly scoped, and addresses the actual contract that was wrong.

Code reference (agent side, confirming the contract)

The selection priority at agent/prompt_builder.py:1449-1454 is exactly what the issue claimed:

project_context = (
    _load_hermes_md(cwd_path)
    or _load_agents_md(cwd_path)
    or _load_claude_md(cwd_path)
    or _load_cursorrules(cwd_path)
)

And the filename set at agent/prompt_builder.py:89:

_HERMES_MD_NAMES = (".hermes.md", "HERMES.md")

First-match-wins, with HERMES.md ahead of AGENTS.md. With the repo previously carrying a 489-line / 28kB HERMES.md at root, that file shadowed AGENTS.md for every Hermes Agent session opened against the WebUI checkout, injecting ~4k tokens of product-positioning copy into the system prompt and hiding the actual contributor guidance that lives in AGENTS.md. The fix is the right shape: move the doc to docs/why-hermes.md so the agent walks past the missing root file and picks up AGENTS.md, while the human-facing comparison remains published and linked from README.md.

Diagnosis

The agent walks cwd then parents up to the git root looking for _HERMES_MD_NAMES. Putting the file under docs/ means a session started with cwd = ~/hermes-webui finds no HERMES.md at ~/hermes-webui/ or at any parent, falls through to _load_agents_md, and now picks up AGENTS.md (which is what was always intended). A session started inside docs/ would also walk parents and miss the moved file — and that is fine, because docs/why-hermes.md is not in _HERMES_MD_NAMES regardless of directory.

Test coverage

The regression test at tests/test_agent_context_docs.py pins both halves of the contract:

def test_root_does_not_shadow_agents_md_with_hermes_context_file():
    repo_root = Path(__file__).resolve().parents[1]
    for name in ("HERMES.md", ".hermes.md"):
        assert not (repo_root / name).exists(), (
            f"{name} at the repository root is auto-loaded by Hermes Agent as "
            "project context before AGENTS.md; long human-facing Hermes overview "
            "docs belong under docs/."
        )

Good — that asserts the negative invariant (no root HERMES.md or .hermes.md) which is exactly what the agent contract requires. The README-link test at the same file pins the published-document side so the doc cannot silently get orphaned by a future rename.

Recommendation

Approve. The change is the minimum repository-side action that fixes #2595, the test pins the constraint so a future contributor cannot accidentally reintroduce a root context file, and there is no runtime behavior change (this is docs-and-test only). The CHANGELOG entry under Unreleased is appropriate. README link updates at lines 71, 92, and 555 all flip to docs/why-hermes.md, which I verified in the diff.

One small note: if you ever want WebUI-specific Hermes Agent operational guidance (i.e. an actual HERMES.md that complements rather than shadows AGENTS.md), a future PR could add a short root HERMES.md whose body just @-includes AGENTS.md plus a couple of WebUI-specific notes. That would satisfy the agent contract (HERMES.md found, project context loaded) while keeping the practical content unified. Not blocking this PR — just a possible future direction once the long marketing document is safely under docs/.

@nesquena-hermes nesquena-hermes closed this pull request by merging all changes into nesquena:master in 6c60925 May 20, 2026
dobby-d-elf pushed a commit to dobby-d-elf/hermes-webui that referenced this pull request May 20, 2026
# Conflicts:
#	CHANGELOG.md
eleboucher pushed a commit to eleboucher/homelab that referenced this pull request May 20, 2026
… 0.51.96) (#593)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/nesquena/hermes-webui](https://github.com/nesquena/hermes-webui) | patch | `0.51.95` → `0.51.96` |

---

### Release Notes

<details>
<summary>nesquena/hermes-webui (ghcr.io/nesquena/hermes-webui)</summary>

### [`v0.51.96`](https://github.com/nesquena/hermes-webui/blob/HEAD/CHANGELOG.md#v05196--2026-05-20--Release-BT-stage-389--8-PR-batch--IPv6-dashboard-link-normalization--configured-title-generation-provider-routing--sidebar-pinned-session-3-cap--external-refresh-sidecar-count-preference--Hermes-overview-docs-relocation--legacy-dedup-timestamp-granularity--custom-provider-models-endpoint-error-surfacing--RuntimeAdapter-Slice-4c-harness-gate-RFC)

[Compare Source](nesquena/hermes-webui@v0.51.95...v0.51.96)

##### Fixed

- **PR [#&#8203;2610](nesquena/hermes-webui#2610 by [@&#8203;AJV20](https://github.com/AJV20) — Preserve square brackets around IPv6 hosts when normalizing browser-only dashboard URLs, so links like `http://[::1]:9119` remain valid after saving instead of being mangled into invalid IPv6 forms. Closes the regression introduced by the URL-sanitization path added in [#&#8203;2533](nesquena/hermes-webui#2533) / v0.51.95 — bracketed IPv6 hosts now round-trip through the dashboard-link save flow unchanged.
- **PR [#&#8203;2612](nesquena/hermes-webui#2612 by [@&#8203;AJV20](https://github.com/AJV20) — Route WebUI session title generation through the configured `auxiliary.title_generation` provider, model, and base URL when present in config, instead of leaving the auxiliary client to silently fall back to the chat model. Users who configure a smaller/cheaper model for title generation (e.g. a fast 8B model on a separate provider) now have that selection honored end-to-end.
- **PR [#&#8203;2618](nesquena/hermes-webui#2618 by [@&#8203;LumenYoung](https://github.com/LumenYoung) — Prefer the persisted sidecar `message_count` over the session-index stored count during external-refresh polling. The metadata-only `/api/session?messages=0` path now reads `Session._metadata_message_count` when sidecar data is available, so legacy sessions whose state.db retains old rows still trip the external-refresh signal correctly on sidecar updates. Composes cleanly with [#&#8203;2604](nesquena/hermes-webui#2604) (the legacy-fallback only applies when the reconciled merged count is zero).
- **PR [#&#8203;2620](nesquena/hermes-webui#2620 by [@&#8203;bengdan](https://github.com/bengdan) — Use second-level timestamp granularity in the legacy message-dedup key. Drops the microsecond fallback in `_normalized_message_timestamp_for_dedup_key()` so transcripts that encode timestamps at different sub-second precisions (e.g. `"10.0"` vs `10.000000`) collapse to the same dedup bucket. Retroactively de-duplicates the dominant failure mode in [#&#8203;2616](nesquena/hermes-webui#2616) without requiring an on-disk session rewrite.
- **PR [#&#8203;2626](nesquena/hermes-webui#2626 by [@&#8203;Michaelyklam](https://github.com/Michaelyklam) (closes [#&#8203;2540](nesquena/hermes-webui#2540)) — Surface named custom-provider `/models` endpoint failures in the model picker instead of silently showing an empty provider group. `_read_custom_endpoint_models` now returns `(models, error)`, so auth/network/HTTP failures propagate as structured `models_endpoint_error` hints on `/api/models` per affected provider. The composer model picker renders the hint as a quiet disabled-option diagnostic; configured fallback models remain selectable. 124 LOC of new regression coverage spans 401/network-error/5xx failure modes plus frontend hook validation.

##### Added

- **PR [#&#8203;2614](nesquena/hermes-webui#2614 by [@&#8203;Michaelyklam](https://github.com/Michaelyklam) (refs [#&#8203;2508](nesquena/hermes-webui#2508)) — Cap sidebar-active pinned sessions at three. Right-clicking a conversation row opens the existing action menu, attempted pins beyond the cap render the menu item as disabled with an explanatory tooltip, and the backend rejects a fourth pin attempt with a structured error so the optimistic frontend can roll back the click. Settles the open question from [#&#8203;2508](nesquena/hermes-webui#2508) on whether pin count is bounded — the answer is three, configurable in a future PR if user demand surfaces.

##### Documentation

- **PR [#&#8203;2619](nesquena/hermes-webui#2619 by [@&#8203;Michaelyklam](https://github.com/Michaelyklam) (closes [#&#8203;2595](nesquena/hermes-webui#2595)) — Move the long human-facing Hermes comparison document from root `HERMES.md` to `docs/why-hermes.md` so Hermes Agent sessions opened in this repository load `AGENTS.md` as the project-specific assistant guidance instead of the marketing overview. README links now point to the new docs path and a regression test (`tests/test_agent_context_docs.py`) prevents root `HERMES.md` / `.hermes.md` context files from silently reappearing.
- **PR [#&#8203;2627](nesquena/hermes-webui#2627 by [@&#8203;Michaelyklam](https://github.com/Michaelyklam) (refs [#&#8203;1925](nesquena/hermes-webui#1925)) — Advance the RuntimeAdapter RFC after the Slice 4b `RunnerRuntimeAdapter` facade shipped in v0.51.94. The RFC now defines the next Slice 4c runner-backend harness gate: feature-flagged runner backend selection, explicit start payload validation, durable status/event observation across WebUI adapter recreation, bounded controls, and a deterministic harness for proving the facade's protocol-translation invariants without requiring the future runner/sidecar to exist.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/593
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
# Conflicts:
#	CHANGELOG.md
bernyforce pushed a commit to bernyforce/hermes-webui that referenced this pull request Jul 29, 2026
# Conflicts:
#	CHANGELOG.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Root HERMES.md is auto-loaded into Hermes Agent context

2 participants