Follow-up to #120339 from its independent re-review.
- Single-flight: the restore runs under an OS lock on <git dir>/hermes-update-pull.claim
(flock on POSIX, msvcrt.locking on Windows; owner pid written for humans). The kernel drops
the lock with its owner, so a dead launch's claim is broken without a check-then-unlink race.
A launch that loses waits up to 10 s, then re-checks: if the marker is gone the tree changed
under it and it returns True (relaunch) instead of importing a half-restored tree; if the
holder is still busy it prints a neutral note and never touches the tree.
- index.lock is removed only by the claim holder and only when no live process has it open
(/proc on Linux; Windows refuses the unlink of an open file; elsewhere the claim is the guard).
- The failure message no longer prints `git reset --hard <pre>`: that wipes the uncommitted
edits the restore keeps. It names git's error and says the next launch retries.
- HEAD already moved is checked before merge/rebase state, so a git killed after committing its
merge but before deleting MERGE_HEAD spends the marker instead of pinning it forever.
- MERGE_HEAD == the marker's target (the updater's own merge, killed mid-conflict): print
`git -C <root> merge --abort`, then relaunch, once per launch (plus the stash name if any).
- `hermes-agent` (agent.legacy_cli:main) now repairs at the top of agent/legacy_cli.py, before
argparse and run_agent; the entry-point spy test covers it.
- Directories git created for added files are removed bottom-up when empty; a dir pre has, or one
holding an untracked file, is kept.