Installer marker files dirtying Git checkouts

NousResearch/hermes-agent · cluster 38529 · hermes cli

Data as of

Nothing open on GitHub. Fix merged in #39707. Check it covers your case.

The short answer

0open issues
0open PRs
9items grouped
Known?
Yes. 9 related items grouped here, 2 issues already closed.
Fix event
A fix was merged to main in PR #39707. Check it covers your case. No release data is tracked.
Tracker
The maintainers' tracker marks this resolved, deciding PRs #39707, #67364. That is separate from the fix event.
Still open
Nothing open on GitHub.

These issues and PRs address installer- and bootstrap-created marker files (.install_method, .hermes-bootstrap-complete) that unintentionally dirty Git working directories, causing repeated autostash loops during updates. Fixes involve gitignoring the files and/or stopping their creation inside Git checkouts.

Open issues0

No open issues.

Open PRs0

No open pull requests.

Fixes on record

Merged to main. A stamp counts the issues a fix is linked to.

  • #39707 fix(cli): gitignore Desktop bootstrap marker so hermes update stops autostashing it

    merged to main

    files: .gitignore, scripts/release.py, tests/hermes_cli/test_update_autostash.py

    Show the diff
    • .gitignore
      @@ -108,6 +108,12 @@ docs/superpowers/*
       # logs, and per-session caches are never artifacts of the codebase.
       .hermes/
       
      +# Desktop/bootstrap install marker written into the managed checkout root by the
      +# bootstrap installer. It is Hermes-managed runtime state, never a code change —
      +# ignore it so `hermes update`'s `git stash push --include-untracked` does not
      +# treat it as a local edit and autostash it on every run (#38529).
      +.hermes-bootstrap-complete
      +
       # Tool Search live-test harness output — non-deterministic model transcripts,
       # regenerated by scripts/tool_search_livetest.py. Never an artifact of the repo.
       scripts/out/
    • scripts/release.py
      @@ -45,6 +45,7 @@
       
       # Auto-extracted from noreply emails + manual overrides
       AUTHOR_MAP = {
      +    "[redacted:email]": "harjothkhara",
           "[redacted:email]": "HeLLGURD",
           "[redacted:email]": "dirtyren",
           "[redacted:email]": "zhaoleibd",
    • tests/hermes_cli/test_update_autostash.py
      @@ -819,3 +819,50 @@ def test_cmd_update_skips_stash_restore_when_reset_fails(monkeypatch, tmp_path,
       
           out = capsys.readouterr().out
           assert "preserved in stash" in out
      +
      +
      +def test_bootstrap_marker_not_autostashed_by_update(tmp_path):
      +    """#38529: the Desktop bootstrap marker must be git-ignored so that
      +    ``hermes update``'s ``git stash push --include-untracked`` does not sweep it
      +    into an autostash on every run.
      +
      +    Behavioral + hermetic: build a throwaway repo that adopts the project's real
      +    ``.gitignore`` (the contract under test), drop the marker, and confirm the
      +    same stash invocation the updater uses leaves it untouched.
      +    """
      +    import shutil
      +    import subprocess
      +
      +    if shutil.which("git") is None:
      +        pytest.skip("git not available")
      +
      +    repo_gitignore = Path(hermes_main.__file__).resolve().parents[1] / ".gitignore"
      +
      +    def git(*args):
      +        return subprocess.run(
      +            ["git", *args], cwd=tmp_path, capture_output=True, text=True, check=True
      +        )
      +
      +    git("init", "-q")
      +    git("config", "user.email", "[redacted:email]")
      +    git("config", "user.name", "t")
      +    (tmp_path / ".gitignore").write_text(repo_gitignore.read_text())
      +    (tmp_path / "tracked.txt").write_text("x\n")
      +    git("add", "-A")
      +    git("commit", "-qm", "init")
      +
      +    marker = tmp_path / ".hermes-bootstrap-complete"
      +    marker.write_text("")
      +
      +    # Exact flags used by hermes update (hermes_cli/main.py).
      +    git("stash", "push", "--include-untracked", "-m", "hermes-update-autostash")
      +
      +    assert marker.exists(), (
      +        ".hermes-bootstrap-complete was swept into the update autostash — it must "
      +        "be listed in .gitignore so `git stash -u` skips it (#38529)."
      +    )
      +    # It must not even register as a dirty/untracked change.
      +    status = subprocess.run(
      +        ["git", "status", "--porcelain"], cwd=tmp_path, capture_output=True, text=True
      +    ).stdout
      +    assert ".hermes-bootstrap-complete" not in status
  • #67364 chore(gitignore): ignore installer .install_method stamp (salvage of #54855)

    merged to main

    files: .gitignore, tests/hermes_cli/test_update_autostash.py

5 PRs closed without merging

From the close comments: duplicate 2 · closed without comment 1 · done elsewhere 1 · partial fix 1

  • #38550 fix(cli): gitignore Desktop bootstrap marker so hermes update stops autostashing it · closed without comment
  • #38555 fix(cli): ignore Desktop bootstrap marker to fix update stash loops · done elsewhere → #38550, #38529, #38542
  • #66216 fix: ignore installer-created .install_method runtime stamp (#66189) · duplicate → #54855
  • #66322 fix(cli): stop creating .install_method in Git checkout (#66189) · partial fix → 211edd5, 48d8483, #66189, #66322, #67364, #54855, #66216, #66723, #374151
  • #66723 chore(gitignore): ignore .install_method installer marker (#66189) · duplicate
Closed issues · 2
  • Closed#38529hermes update repeatedly autostashes Desktop bootstrap marker .hermes-bootstrap-complete
  • Closed#66189[Bug]: Installer-created .install_method dirties Git checkouts
How this cluster was grouped
  • Link evidence (partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text.
  • Members outside that structural core may belong to a different underlying problem.
  • Pairwise link density 0.20: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. 1.00 means every pair is linked.

Pick up a Lab task

Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.

Open the Lab

At a glance

Subsystem
hermes cli
Merged PRs
#39707, #67364
Closed issues
2
Attempts
5 PRs closed without merging
Fix link checked
22 Jul 2026

For your agent

The same facts, typed.