Prepare Hermes for a safe `hermes update` when there are local repo edits, patch artifacts, untracked files, multiple profiles, or machine-specific customizations that must survive the update. Use whenever the user asks about updating Hermes safely, preserving local changes across update, checking if current work is update-proof, refreshing `~/.hermes/patches`, auditing what the post-merge hook will restore, replaying local improvements after update, or verifying that default and gpt profiles still work afterward. Always use this before running `hermes update` on a dirty Hermes repo.
Use this skill for Hermes self-updates on this machine when the repo is dirty or local behavior matters.
This is not just “run hermes update.” The real job is:
hermes update actually doesVerified from hermes_cli/main.py:
origin/main.Important: this is helpful, but it is not a semantic smart merge. It preserves work at the git level. It does not know which local changes are intentional, stale, or dangerous.
Also verified live on this machine:
~/.hermes/hermes-agent/.git/hooks/post-merge restores selected .new files from ~/.hermes/patches/~/.hermes/patches/*.patchSo update survival here is two layers:
Treat ~/.hermes/patches/ as live system state, not as an archive.
Never assume current local work is update-proof just because:
hermes update auto-stashes, orCheck the live dirty tree against the live patch inventory every time.
Also classify where each durable change should live before updating.
If the question is really about storage/placement rather than update mechanics, read the shared durable-state skill first. The update checklist should stay procedural; the placement model lives in hermes__shared-durable-state-architecture.
Use this skill when the user says things like:
hermes update keep our changes?”Start with evidence, not memory.
Run these checks first:
cd ~/.hermes/hermes-agent
git status --short
find ~/.hermes/patches -maxdepth 1 -type f | sort
Read the live hook if behavior matters:
~/.hermes/hermes-agent/.git/hooks/post-mergeAlso inspect profile-specific state if the current work depends on it:
~/.hermes/profiles/gpt/~/.hermes/config.yaml~/.hermes/profiles/gpt/config.yaml.env files~/.hermes/profiles/<profile>/cron/jobs.jsonProduce four buckets:
Do not continue until each current change has been classified.
Before trusting the patch system, compare the dirty repo to the patch inventory.
Use this pattern:
cd ~/.hermes/hermes-agent
for p in ~/.hermes/patches/*.patch; do
[ -f "$p" ] || continue
grep '^diff --git' "$p" | sed 's|^diff --git a/||; s| b/.*$||'
done | sort -u > /tmp/patched-files.txt
git diff --name-only HEAD | sort -u > /tmp/wt-files.txt
comm -23 /tmp/wt-files.txt /tmp/patched-files.txt
Interpret each uncovered file:
Do not leave meaningful files in a “maybe stash will save it” state unless you are intentionally accepting that risk.
Refresh patches from the live intended diff, grouped by feature.
Pattern:
cd ~/.hermes/hermes-agent
git --no-pager diff -- path/to/file1 path/to/file2 > ~/.hermes/patches/feature-name.patch
Prefer feature-grouped patches over one giant anonymous patch.
Good groups look like:
If the post-merge hook restores a .new file already, refresh that file from the live repo.
Pattern:
cp path/to/new_file ~/.hermes/patches/new_file.py.new
If the file is important, also create a real diff-from-empty patch so it can be recreated more robustly:
git diff --no-index -- /dev/null path/to/new_file > ~/.hermes/patches/new-file.patch
Remove, rename, or archive anything you do NOT want restored after update.
This matters a lot for deleted tests/tools. A stale .new file can resurrect dead code after update.
Not everything important lives in ~/.hermes/hermes-agent.
Check and document any runtime state that the update will not manage for you:
.env contents and permissionsFor each non-git dependency, record:
For non-trivial local changes, do a dry-run in a scratch worktree before touching the real repo.
Use this exact pattern:
cd ~/.hermes/hermes-agent
git fetch origin
rm -rf /tmp/hermes-merge-test
git worktree add /tmp/hermes-merge-test origin/main
git --no-pager diff HEAD > /tmp/local-mods.patch
cd /tmp/hermes-merge-test
git apply --3way --check /tmp/local-mods.patch 2>&1
If it reports conflicts, inspect them in the worktree before running the real update.
This gives you a conflict map without risking the live repo or forcing an immediate restart cycle.
Cleanup:
cd ~/.hermes/hermes-agent
git worktree remove /tmp/hermes-merge-test --force
Before declaring “good to update,” run an independent verification pass using a subagent.
The verifier should answer:
.new restoresThe verifier must not rely on the main agent’s conclusions. It should inspect the live repo, live patch directory, and live hook itself.
Only run update after:
Then run:
cd ~/.hermes/hermes-agent
hermes update
If running from messaging, remember /update uses the same underlying update logic plus file-based prompt forwarding.
After update:
If stash restore failed during update, do not hand-wave it. Identify which files came back and which didn’t.
Run verification in layers.
git status --shortpy_compile or equivalent syntax checks for changed Python filesRun the most relevant targeted tests for the changed features. At minimum, include tests touching:
Verify the user path, not just code shape:
If both default and gpt matter, verify both explicitly. Do not assume one profile proving healthy means the other is fine.
Check:
~/.hermes/skills~/.hermes/profiles/gpt/skills.envDo not say “good to update” or “update-safe” until you can state, with evidence:
If all meaningful changes are either patch-protected, safely reproducible, or intentionally accepted as manual replay work, then give the go-ahead.
.new file resurrects deleted codeCheck ~/.hermes/patches/*.new first.
A familiar patch filename means nothing unless it matches today’s intended diff.
Split it before update. Anonymous blobs are how work gets half-preserved.
If it matters, back it up explicitly. Don’t rely on luck.
If mem0, cron, plugins, or venv packages matter, record the rebuild steps.
Use the independent verifier lane.
When finishing an update-prep run, answer in plain English:
If not ready, stop with the smallest concrete blockers and the exact next fixes.