refactor(checkpoints): slim the profile-rename rekey and name it as a checkpoint_manager sibling

Follow-up to the cherry-picked fix from #112724 (@poijygfdyy):

- tools/checkpoint_profile_migration.py -> tools/checkpoint_manager_profile_rename.py, the
  repo's `<stem>_<topic>.py` sibling convention for code that extends checkpoint_manager.
- Replace the fail-closed target-collision check plus temp-file/rollback choreography with an
  idempotent rekey: every step overwrites and the old project metadata is removed last, so a
  mid-way failure is repaired by `hermes profile migrate-identity` redoing the same writes.
  A genuine collision cannot occur — `profiles/<new>` must not exist for the rename to run.
  192 -> 98 lines.
- Metadata/ledger writes go through the same idiom as checkpoint_manager itself
  (`_register_project` plain write, `_save_ledger`), dropping the private temp-file helpers.
- Keep the git-present precondition as a single early check: without git the ref cannot move
  and rekeying only the metadata would orphan the history.
- Test: `create_profile` now seeds `workspace/`, so the fixture uses `project/`; add the control
  assertion that a workdir outside the profile dir keeps its history unchanged.
- Docs: the profile rename / migrate-identity reference notes that checkpoint history is preserved.

Fixes #112973
This commit is contained in:
teknium1
2026-09-16 09:57:11 -07:00
committed by Teknium
parent 8a2c9edac6
commit c055eee1fe
5 changed files with 112 additions and 198 deletions

View File

@@ -245,7 +245,10 @@ hermes profile rename mybot assistant
The rename also migrates the profile's persisted session/routing identity — session keys
(`agent:<old>:*`), `sessions.profile_name`, heartbeats, and routing/delivery rows — to the new
name. A live multiplexed gateway owns that migration (it holds the routing index in memory), so
when it is running the CLI delegates to it.
when it is running the CLI delegates to it. Checkpoint (`/rollback`) history of workspaces that
live inside the profile directory is rekeyed to their new path as well, so it stays reachable
after the rename; `hermes profile migrate-identity` retries that step too if it was reported as
failed.
## `hermes profile migrate-identity`