On a custom branch the updater runs `git merge --no-edit origin/<branch>` inside the marker window.
Its files are the merge of both sides, a blob that is neither pre nor target, so the restore took
them for user edits: it put the upstream-only files back to pre, kept the merged ones and spent the
marker, leaving a mixed tree (a real random-kill of that merge: 104 of 500 trials broken).
- _early_recovery: when pre and target diverge, `git merge-tree --write-tree pre target` gives the
tree the merge was writing; its blobs (and prefixes of them, for a file cut short) count as git's
like the target's. Conflicted paths, and on git < 2.38 every path both sides changed, count as
git's whatever their content. Paths with a newline are hashed one by one (`--stdin-paths` is
newline-delimited). The docstring lists the by-design limits.
- run_agent (`hermes-agent`) and acp_adapter.entry (`hermes-acp`) never import hermes_cli.main, so
they now run the same restore right after hermes_bootstrap (run_agent only when hermes_cli.main is
not loaded, since it is also a library module).
- Tests: the second test kills inside a clean custom-branch merge (merged file, upstream-only file,
a cut-short file, a user edit); the first pins that each console script's entry module imports
no other checkout module before the restore runs. Both red on the previous head.
- evals/update_pipeline/interrupted_pull_ab.sh gains scenario E: a kill inside the custom-branch
merge, then the `hermes-agent` import.