|

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

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