Hermes Agent
Hermes stops delegated workers from sharing or dirtying parent workspaces
Three Hermes patches separate scratch children after a claimed Kanban root, move worktree exclusions out of the parent’s tracked ignore file, and share successful full-verification evidence across sessions for the same root. Isolation and proof are becoming workspace properties rather than session folklore.
NousResearch/hermes-agent PR #103325 is the inspected primary source: “fix(kanban): scratch decompose children must not inherit a claimed root's workspace_path.” The related records were inspected as supporting context rather than independent confirmation.
The facts
- NousResearch/hermes-agent PR #103325 was created 2026-09-05T00:51:26Z and was open at inspection; its title is “fix(kanban): scratch decompose children must not inherit a claimed root's workspace_path.” - NousResearch/hermes-agent PR #103324 was created 2026-09-05T00:50:32Z and was open at inspection; its title is “fix(delegate): stop subagent worktree isolation from mutating tracked.gitignore.” - NousResearch/hermes-agent PR #103315 was created 2026-09-05T00:29:20Z and was open at inspection; its title is “fix(agent): share full verify evidence across sessions.” - The repository reported 241491 stars, 39723 open issues, default branch main, and last push 2026-09-05T00:24:54Z. - The latest tagged-release baseline checked was v2026.8.31 published 2026-08-31T19:29:49Z.
What changed
NousResearch/hermes-agent PR #103325 reports: Problem decompose_triage_task() (hermes_cli/kanban_db.py, _insert_decomposed_child) deliberately leaves a worktree-kind child's workspace_path unset so dispatch materializes a distinct /.worktrees/ per sibling. scratch children got no such treatment: they fell into the child_ws_kind == root_ws_kind branch and inherited the root's literal workspace_path verbatim. That's harmless while the root has never been claimed (workspace_path is NULL, so children get NULL too and resolve their own workspaces/ at dispatch). But once the root has been claimed at least once, the dispatcher has already stamped a concrete path onto it via set_workspace_path(). Decomposing *that* root pins every scratch sibling to the same directory, so concurrently dispatched workers all write into one shared dir instead of isolated per-task scratch dirs — silent cross-contamination with no error anywhere in the board state, diagnostics, or run logs. Fixes #103303. Fix Route scratch through the same "leave workspace_path unset" branch already used for worktree: dir-kind inheritance (the intentional shared-checkout case) is untouched. Per-child explicit workspace_path overrides still win, exactly as before. Test Added test_decompose_scratch_children_get_own_workspace in tests/hermes_cli/test_kanban_decompose_db.py, modeled on the existing worktree-isolation regression test: creates a scratch-kind triage root, stamps a concrete workspace_path onto it (simulating a prior claim), decomposes it, and asserts both children come back with workspace_path IS NULL. Confirmed the test fails without the fix (git checkout HEAD~1 -- hermes_cli/kanban_db.py equivalent — actually verified by stashing the fix hunk before it was committed): And passes with the fix
NousResearch/hermes-agent PR #103324 reports: What does this PR do? tools/subagent_worktree.py::create_subagent_worktree() unconditionally appends.worktrees/ to the parent repository's **tracked**.gitignore on every successful worktree creation. That's a write to a tracked file in the parent checkout, which contradicts the module's own isolation contract that the parent's checkout stays untouched while a child works in its own worktree. This PR fixes the mutation side of #103302 by switching _ensure_gitignore_entry() to write the.worktrees/ exclusion into.git/info/exclude instead — untracked, local-only, and never touches anything the parent repo tracks or that git status/git diff in the parent checkout would ever show. (Note: #103302 also reports that isolation silently degrades to a shared cwd when no git anchor can be resolved. That part is already addressed by open PR 97228, which adds delegation.worktree_repo_root and upgrades the relevant logger.debug calls to visible logger.warnings at the delegate_tool.py call site. This PR only fixes the still-unaddressed.gitignore write, to avoid duplicating that work.) Related Issue Fixes #103302 Type of Change [x] Bug fix (non-breaking change that fixes an issue) Changes Made tools/subagent_worktree.py: _ensure_gitignore_entry() now resolves the repo's common.git directory (via git rev-parse --git-common-dir, so it works correctly even when repo_root is itself a linked worktree) and appends the.worktrees/ entry to /info/exclude instead of /.gitignore. tests/tools/test_subagent_worktree.py: test_create_makes_isolated_worktree now asserts.gitignore is **not** created in the parent repo, and that.git/info/exclude gained the.worktrees/ entry instead. How to Test Reproduction
NousResearch/hermes-agent PR #103315 reports: What does this PR do? A passing full hermes verify now clears stale edit state for every session tracking the same workspace root. Targeted and failed runs stay session-scoped, and edits recorded after the verify started remain stale. Related Issue Fixes #103271 Type of Change [x] Bug fix (non-breaking change that fixes an issue) [x] Tests (adding or improving test coverage) Changes Made Share successful full verify evidence across existing session state rows for the same root. Add cross-session regression coverage for full passes, targeted passes, full failures, and later edits. How to Test 1. Mark a workspace edited under a non-default session. 2. Run hermes verify without HERMES_SESSION_ID. 3. Confirm the original session no longer receives the verify-on-stop nudge; a later edit makes it stale again. Checklist Code [x] I've read the Contributing Guide [x] My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.) [x] I searched for existing PRs to make sure this isn't a duplicate [x] My PR contains **only** changes related to this fix/feature (no unrelated commits) [ ] I've run pytest tests/ -q and all tests pass [x] I've added tests for my changes (required for bug fixes, strongly encouraged for features) [x] I've tested on my platform: macOS 26.6 Documentation & Housekeeping [x] I've updated relevant documentation (README, docs/, docstrings) — or N/A [x] I've updated cli-config.yaml.example if I added/changed config keys
Why it matters
Parallel workers are not isolated if siblings inherit one directory or setup dirties the parent checkout; verification is not durable if every session forgets the same full pass. The practical test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.
Current
The primary record was open when captured on 2026-09-05. The tagged-release baseline was v2026.8.31 published 2026-08-31T19:29:49Z. Repository metadata, source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.
Evidence
The primary URL is https://github.com/NousResearch/hermes-agent/pull/103325. Supporting records are https://github.com/NousResearch/hermes-agent/pull/103324 and https://github.com/NousResearch/hermes-agent/pull/103315. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.
Source boundary
Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.
Operator take
Materialize a distinct scratch or worktree path per child, keep local exclusions in Git metadata, and share only full successful verification while preserving later-edit staleness. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.
Caveat
Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.
Source inspected; source state, environment and release boundary remain explicit.