docs: rename spec — keep name/repo decoupling, add case-aware prompt
Author:
Chris Tusa <chris.tusa@leafscale.com>
Date:
Jul 15, 2026 13:26
Changeset:
00a18db4a254ec1c582b9f386f66feb695ec3b1b
Branch:
default
Changed files:
Diff
diff -r 34780448f6f9 -r 00a18db4a254 docs/superpowers/specs/2026-07-15-repoman-rename-design.md --- a/docs/superpowers/specs/2026-07-15-repoman-rename-design.md Wed Jul 15 13:15:35 2026 -0500 +++ b/docs/superpowers/specs/2026-07-15-repoman-rename-design.md Wed Jul 15 13:26:05 2026 -0500 @@ -79,6 +79,44 @@ `path`/`source` and the Claude slug are derived from `repo` (unchanged), so history stays valid automatically. +**Decoupling is load-bearing, not a wart.** It is the only way to give a nested +or awkwardly-named repo path a valid, short container identity — a container +cannot be named e.g. `leafscale-infrastructure/portal.leafscale.com` (slashes, +length, charset all fail `incus.validate_name`), so the `portal` project maps +that nested path to the short name `portal`. Enforcing `repo == name` was +considered and rejected: it would break this active pattern. The predictability +concern it raises is addressed by the case-aware confirmation prompt below, which +makes the two-tier behavior self-explaining at the moment it matters. + +### Confirmation prompt (case-aware) + +The prompt states exactly which layers move and, in the decoupled case, why the +repo dir is left alone and names it explicitly: + +``` +# coupled (proj.repo == <old>): +repoman rename driftohm mist + will move: + - incus container driftohm → mist + - registry entry driftohm → mist + - repo directory ~/repos/driftohm → ~/repos/mist + your source is moved intact, never deleted. + continue? [y/N] + +# decoupled (proj.repo != <old>): +repoman rename portal gateway + will move: + - incus container portal → gateway + - registry entry portal → gateway + repo directory unchanged (~/repos/leafscale-infrastructure/portal.leafscale.com) + — this project's dir name is decoupled from its container name. + continue? [y/N] +``` + +With `--migrate-claude-history` a `- claude history <old-slug> → <new-slug>` +line is added in the coupled case (and omitted, with the dir, in the decoupled +case). + ## Algorithm (idempotent, resumable) Inspect every layer first, then change only what is still on the old name. The @@ -98,9 +136,10 @@ different containers, or two registry entries) → `Err` — rename must not merge or clobber. (The benign "already partly renamed" states — same project, some layers ahead — are allowed and resumed.) -3. **Confirm** unless `--yes`: print the concrete plan (which layers will move, - old → new), and state plainly that the source repository contents are moved - intact, never deleted. Use `console.confirm_default_no`. +3. **Confirm** unless `--yes`: print the case-aware plan (see *Confirmation + prompt* above) — the exact layers that will move, old → new, and in the + decoupled case the named repo dir that will be left untouched and why. Use + `console.confirm_default_no`. 4. Open the per-invocation log (after confirmation), verb `"rename"`. 5. **Stop** the container if running; remember the prior run-state. 6. **Host dir** (directory tier only): if `<repos_root>/<old>` exists and