Merge pull request #44545 from NousResearch/hermes-worktree-code

fix(coding): don't expose primary worktree path in coding context
This commit is contained in:
brooklyn! 2026-06-11 19:35:18 -05:00 committed by GitHub
commit afe53708ee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 3 deletions

View file

@ -711,10 +711,13 @@ def build_coding_workspace_block(cwd: Optional[str | Path] = None) -> str:
lines.append("- Branch: (detached HEAD)")
# Linked worktree: the per-worktree git dir differs from the shared common dir.
# We surface the fact that it's a worktree (so the model knows branches/stashes
# are shared state) but deliberately do NOT expose the primary tree path —
# giving the model a second absolute path causes it to sometimes run commands
# in the wrong directory.
git_dir, common_dir = _git(root, "rev-parse", "--git-dir"), _git(root, "rev-parse", "--git-common-dir")
if git_dir and common_dir and Path(git_dir).resolve() != Path(common_dir).resolve():
main_tree = Path(common_dir).resolve().parent
lines.append(f"- Worktree: linked (primary tree at {main_tree})")
lines.append("- Worktree: linked (git state shared with primary tree)")
dirty = [f"{n} {label}" for label, n in (
("staged", counts["staged"]), ("modified", counts["modified"]),

View file

@ -1,7 +1,9 @@
"""Tests for agent.coding_context — RuntimeMode seam, resolver, toolset, git probe."""
import json
import os
import subprocess
import shutil
from pathlib import Path
import pytest
@ -13,12 +15,13 @@ def _git_init(path):
env = {
"GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@t",
"GIT_COMMITTER_NAME": "t", "GIT_COMMITTER_EMAIL": "t@t",
"HOME": str(path),
}
for args in (
["init", "-q", "-b", "main"],
["commit", "-q", "--allow-empty", "-m", "init commit"],
):
subprocess.run(["git", "-C", str(path), *args], check=True, env={**env, "HOME": str(path)})
subprocess.run([shutil.which("git"), "-C", str(path), *args], check=True, env=env)
# ── resolver ──────────────────────────────────────────────────────────────
@ -158,6 +161,29 @@ class TestProjectFacts:
block = cc.build_coding_workspace_block(tmp_path)
assert "Context files: AGENTS.md" in block
def test_worktree_detected_without_primary_path(self, tmp_path):
# A linked worktree should be detected, but the output must NOT contain
# the absolute path to the primary tree — exposing that path causes the
# model to sometimes run commands in the wrong directory.
main_tree = tmp_path / "main"
main_tree.mkdir()
_git_init(main_tree)
worktree = tmp_path / "worktree"
subprocess.run(
["git", "-C", str(main_tree), "worktree", "add", "-b", "wt-branch", str(worktree)],
check=True,
env={"PATH": os.environ.get("PATH", ""), "HOME": str(tmp_path),
"GIT_AUTHOR_NAME": "t", "GIT_AUTHOR_EMAIL": "t@t",
"GIT_COMMITTER_NAME": "t", "GIT_COMMITTER_EMAIL": "t@t"},
)
block = cc.build_coding_workspace_block(worktree)
assert "Worktree: linked" in block
# The primary tree path must NOT appear anywhere in the output.
assert str(main_tree.resolve()) not in block
assert str(main_tree) not in block
# The worktree root IS the reported root.
assert f"Root: {worktree.resolve()}" in block or "Root:" in block
def test_marker_only_project_gets_snapshot_without_git(self, tmp_path):
# A non-git project (manifest only) still gets a workspace snapshot —
# just without the git lines.