From 7ef1c4f5e08a9198cd9f83497ffd922faa2bdcb8 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Sat, 4 Apr 2026 00:20:13 +0300 Subject: [PATCH] fix: apply lessons from real-world migration test run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on analysis of a live migration (v1.2.42 -> v1.2.47): 1. Absolute worktree paths: Bash tool resets cwd between calls, so relative cd .upgrade-worktree fails. Store PROJECT_ROOT and WORKTREE as absolute paths, use them throughout. 2. Smarter tier assessment: discount files from skill merges when counting — a fork with 3 skills and no other changes is Tier 2, not Tier 3 just because 24 files changed. 3. Inter-skill conflict analysis: new "Skill Interactions" section in the migration guide captures conflicts between applied skills (duplicate declarations, conflicting env var handling). 4. Cleaner swap recipe: use git reset --hard to the upgrade commit instead of git checkout -B intermediate branch. Backup tag preserves rollback. Copy guide to /tmp before worktree removal. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/migrate-nanoclaw/SKILL.md | 69 ++++++++++++++++++------ 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/.claude/skills/migrate-nanoclaw/SKILL.md b/.claude/skills/migrate-nanoclaw/SKILL.md index d1075a2..a158107 100644 --- a/.claude/skills/migrate-nanoclaw/SKILL.md +++ b/.claude/skills/migrate-nanoclaw/SKILL.md @@ -22,6 +22,7 @@ Two phases: **Extract** (build the migration guide) and **Upgrade** (use it). If - Data directories (`groups/`, `store/`, `data/`, `.env`) are never touched — only code. - Be helpful: offer to do things (stash, commit, stop services) rather than telling the user to do them. - **Use sub-agents for exploration.** Spawn haiku sub-agents to explore the codebase, trace skill merges, diff files, and identify customizations. This keeps the main context focused on the user conversation and decision-making. +- **Always use absolute paths in worktrees.** The Bash tool resets the working directory between calls. Never use relative `cd .upgrade-worktree` — always use the full absolute path: `cd /absolute/path/.upgrade-worktree && `. Store the worktree absolute path in a variable at creation time and reference it throughout. - **Balance exploration and asking.** Don't bombard the user with questions when you can figure things out from the code. Don't burn endless tokens exploring when the user could clarify in one sentence. Use sub-agents to explore first, then ask the user targeted questions about things that are ambiguous or where intent isn't clear from the code alone. - **Scale effort to complexity.** Not every migration needs the full process. Assess the scope early and take the lightest path that fits. @@ -72,9 +73,10 @@ Conditions: ### Tier 3: Complex Conditions (any of): -- Large total diff (15+ changed files) or many new files added (indicates many skills applied) -- Lots of insertions/deletions suggesting deep source changes -- Many skills applied (the presence of many new files — channel files, skill directories — is the signal, not per-file analysis) +- Many new files added (indicates many skills applied) — discount files that come purely from skill merges when assessing complexity; a fork with 3 skills and no other changes is simpler than it looks by file count alone +- Deep source changes to core files (`src/index.ts`, `src/container-runner.ts`, etc.) beyond what skills introduced +- Lots of insertions/deletions in user-authored code (not skill-merged code) +- Many skills applied (3+) AND the user confirms or sub-agents find customizations on top of them Use the full process: multiple sub-agents in parallel, directory-based guide, migration plan. @@ -150,6 +152,13 @@ Each sub-agent task: > 4. Assess detail level: could a fresh Claude session reproduce this from intent alone, or does it need specific code snippets, API details, import paths? > 5. For non-standard changes, extract the key code, imports, API calls, and configurations verbatim. +**Inter-skill conflicts:** If multiple skills are applied, spawn an additional sub-agent to check for interactions between them. Look for: +- Duplicate declarations (same variable/constant defined by two skill branches) +- Conflicting approaches (one skill throws on missing env var, another provides a fallback) +- Shared files modified by multiple skills + +Document any findings in the "Skill Interactions" section of the migration guide so they can be resolved after skill branches are re-merged during upgrade. + ## 1.5 Confirm with user After sub-agents report back, compile the findings and present to the user. @@ -205,6 +214,15 @@ List each skill with its branch name. These are reapplied by merging the upstrea Custom skills (user-created, not from upstream): `.claude/skills/my-custom-skill/` — copy as-is from main tree. +## Skill Interactions + +(Document known conflicts or interactions between applied skills. +When two or more skills modify the same file or depend on shared +config, describe the conflict and how to resolve it after merging. +Example: skill A and skill B both add a PROXY_BIND_HOST declaration — +after merging both, deduplicate. Or: skill A throws if ENV_VAR is +missing, but skill B provides a fallback — use the fallback version.) + ## Modifications to Applied Skills ### : @@ -334,9 +352,13 @@ Ask (AskUserQuestion) to proceed or abort. ## 2.3 Create upgrade worktree ```bash +PROJECT_ROOT=$(pwd) git worktree add .upgrade-worktree upstream/$UPSTREAM_BRANCH --detach +WORKTREE="$PROJECT_ROOT/.upgrade-worktree" ``` +Store `$PROJECT_ROOT` and `$WORKTREE` as absolute paths. Use `$WORKTREE` in all subsequent commands — never `cd .upgrade-worktree` with a relative path. + ## 2.4 Reapply skills in worktree For each skill listed in the migration guide's "Applied Skills" section: @@ -344,7 +366,7 @@ For each skill listed in the migration guide's "Applied Skills" section: 1. Check if branch exists: `git branch -r --list "upstream/$branch"` 2. If yes, merge it in the worktree: ```bash - cd .upgrade-worktree && git merge upstream/skill/ --no-edit && cd .. + cd "$WORKTREE" && git merge upstream/skill/ --no-edit ``` 3. If missing, warn the user (skill may have been removed or renamed upstream). 4. If any skill merge conflicts, stop and tell the user — the skill needs updating for the new upstream. @@ -369,7 +391,7 @@ For behavior customizations (CLAUDE.md files): copy from the main tree. These ar ## 2.6 Validate in worktree ```bash -cd .upgrade-worktree && npm install && npm run build && npm test; cd .. +cd "$WORKTREE" && npm install && npm run build && npm test ``` If build fails, show the error. Fix only issues caused by the migration. If unclear, ask the user. @@ -389,13 +411,13 @@ If testing live: 2. Symlink data into the worktree: ```bash - ln -s $(pwd)/store .upgrade-worktree/store - ln -s $(pwd)/data .upgrade-worktree/data - ln -s $(pwd)/groups .upgrade-worktree/groups - ln -s $(pwd)/.env .upgrade-worktree/.env + ln -s "$PROJECT_ROOT/store" "$WORKTREE/store" + ln -s "$PROJECT_ROOT/data" "$WORKTREE/data" + ln -s "$PROJECT_ROOT/groups" "$WORKTREE/groups" + ln -s "$PROJECT_ROOT/.env" "$WORKTREE/.env" ``` -3. Start from worktree: `cd .upgrade-worktree && npm run dev` +3. Start from worktree: `cd "$WORKTREE" && npm run dev` 4. Ask the user to send a test message from their phone. Wait for them to confirm it works. @@ -403,23 +425,40 @@ If testing live: 6. Clean up symlinks: ```bash - rm .upgrade-worktree/store .upgrade-worktree/data .upgrade-worktree/groups .upgrade-worktree/.env + rm "$WORKTREE/store" "$WORKTREE/data" "$WORKTREE/groups" "$WORKTREE/.env" ``` ## 2.8 Swap into main tree +The swap must be done carefully — the worktree has the upgraded code, but main needs to point to it cleanly. Use absolute paths throughout. + ```bash -UPGRADE_COMMIT=$(cd .upgrade-worktree && git rev-parse HEAD) -git checkout -B upgrade-staging $UPGRADE_COMMIT -git worktree remove .upgrade-worktree --force +# 1. Capture the worktree HEAD before removing it +WORKTREE_PATH=$(cd "$PROJECT_ROOT/.upgrade-worktree" && pwd) +UPGRADE_COMMIT=$(git -C "$WORKTREE_PATH" rev-parse HEAD) + +# 2. Copy the migration guide out of the worktree before removing it +cp -r "$WORKTREE_PATH/.nanoclaw-migrations" /tmp/nanoclaw-migrations-backup 2>/dev/null || true + +# 3. Remove the worktree +git worktree remove "$WORKTREE_PATH" --force + +# 4. Point the current branch at the upgraded commit +git reset --hard $UPGRADE_COMMIT + +# 5. Restore the migration guide and update its hashes +cp -r /tmp/nanoclaw-migrations-backup/* .nanoclaw-migrations/ 2>/dev/null || true +rm -rf /tmp/nanoclaw-migrations-backup ``` -Copy the migration guide back and update its header hashes. Offer to commit: +Update the guide's header hashes to reflect the new state. Offer to commit: ```bash git add .nanoclaw-migrations/ git commit -m "chore: upgrade to upstream $(git rev-parse --short upstream/$UPSTREAM_BRANCH)" ``` +Do NOT use `git checkout -B` to create an intermediate branch — this caused issues in practice. The `git reset --hard` to the upgrade commit is the cleanest path since the backup tag already preserves the pre-upgrade state. + ## 2.9 Post-upgrade Run `npm install && npm run build` in the main tree to confirm.