Seafile Retirement Plan

Goal: Retire Seafile — scrub every live reference, relocate the three repos to flat C:\Projects\ homes (claude-personal, yggdrasil, odin-codin), and re-wire ~/.claude/ — leaving a working single-machine environment with no Seafile dependency.

Approach: Two phases. Phase A (this session, in the session-2026-06-18 worktree): all git-tracked scrub/repoint edits + the memory triage + authoring the two handoff scripts, committed. Phase B (Brad runs after the session closes): an idempotent relocate-claude.ps1 moves the repos, migrates memory, repoints live settings, and re-links ~/.claude/, gated by self-check-claude.ps1. The old C:\Seafile\Claude\ folder is left intact for manual deletion.

Design source: working/seafile-retirement-design.md

Isolation: Already satisfied — this work runs in the session-2026-06-18 worktree off main. /save-progress disposes it (merge to main) before Phase B, since a registered worktree breaks when its parent repo moves.

A note on paths: Phase A edits repoint to the new C:\Projects\… homes while the files still physically live at C:\Seafile\…. That transient mismatch is expected — Phase B's move reconciles reality to the docs.


Phase A — in-session edits (git-tracked)

Task 1: Repoint relink.ps1

Touches: claude-personal/skills/new-machine-setup/relink.ps1 (currently personal/skills/new-machine-setup/relink.ps1).

Change the base/repo variables and the two literal personal\… paths:

  • $lib = 'C:\Seafile\Claude'$lib = 'C:\Projects'
  • $repos = 'personal', 'yggdrasil', 'odin-codin'$repos = 'claude-personal', 'yggdrasil', 'odin-codin'
  • The CLAUDE.md symlink line (~L76): "$lib\personal\CLAUDE.md""$lib\claude-personal\CLAUDE.md"
  • The repo-settings line (~L83): "$lib\personal\claude-config\settings.json""$lib\claude-personal\claude-config\settings.json"
  • Update the .SYNOPSIS header comment that says "into the Seafile library" → the flat-C:\Projects\ framing.

Optional robustness (not required for the move — the relocate script's pre-clean covers it): harden Remove-IfLink so a stale junction whose target has moved is removed before re-creation.

Done when: relink.ps1 references only C:\Projects / claude-personal and no Seafile. Confirm by: rg -i seafile claude-personal/skills/new-machine-setup/relink.ps1 returns nothing; re-read the variable block + the two link lines together.

Task 2: Rewrite new-machine-setup to the portable model

Touches: claude-personal/skills/new-machine-setup/SKILL.md and …/evals/evals.json.

Rewrite the skill from "install the Seafile client + sync the library" to "get the three repos onto the machine — GitHub clone (eventually) / thumb-drive copy / manual paste — placed at C:\Projects\{claude-personal,yggdrasil,odin-codin}, then run relink.ps1." Specifically:

  • Frontmatter description — drop the Seafile framing and the "Seafile symlinks" trigger; describe it as wiring ~/.claude/ to the repos wherever they landed.
  • Drop the "Seafile Details" section (server / library name / sync path).
  • Repoint every C:\Seafile\Claude\… path to C:\Projects\… (the automated relink invocation ~L41, the by-hand block ~L132, the "Standard File Structure" footer ~L157).
  • Reword the "doesn't ride Seafile sync" lines for settings.json (~L98) and plugins — they're machine-local for their own reasons (app-written / per-machine install), not because of Seafile.
  • Keep intact: the GitKraken-hook disable section, the settings.json reconcile-by-hand section, the Windows Dev-Mode/mklink gotcha, the Verify block, the Mac/Linux placeholder.
  • evals/evals.json — rewrite the 3 Seafile-framed prompts + expected-outputs to the portable framing (e.g. "I copied my Claude repos to C:\Projects\ on a new machine — how do I wire up ~/.claude?").

Done when: the skill describes the portable model end-to-end; no Seafile remains in either file. Confirm by: rg -i seafile claude-personal/skills/new-machine-setup/ returns nothing; re-read SKILL.md top-to-bottom together for coherence (the rewrite is prose, so the human read is the gate).

Task 3: Repoint claude-config (README + settings snapshot)

Touches: claude-personal/claude-config/README.md and claude-personal/claude-config/settings.json.

  • settings.json — the two hook command paths C:/Seafile/Claude/personal/hooks/…C:/Projects/claude-personal/hooks/…; remove the now-dead "Read(//C/Seafile/Claude/**)" allow (the existing "Read(//C/Projects/**)" covers the new homes).
  • README.md — repoint the hook-path references and the Copy-Item re-snapshot one-liner; reword "All paths sit under the standardized C:\Seafile\Claude\ library root, so the file is machine-independent" → the C:\Projects\ framing.

Done when: both files reference only C:\Projects paths; no Seafile. Confirm by: rg -i seafile claude-personal/claude-config/ returns nothing; re-read the settings hook block + the README path lines together.

Task 4: Rewrite personal CLAUDE.md Machine-Setup + reconcile the commit convention

Touches: claude-personal/CLAUDE.md and claude-personal/.gitignore.

  • Machine Setup section — rewrite "Standard paths," the "Seafile sync" subsection, and "Layered configuration" to drop Seafile-as-sync and describe the flat C:\Projects\ layout: three sibling repos (claude-personal, yggdrasil, odin-codin) as top-level peers, no library root. ~/.claude/ is still wired by relink.ps1; the repos get onto a machine by clone/copy (forward-reference the eventual GitHub remotes + the cloud move without committing to dates). Keep (reworded to drop Seafile framing): the mklink/Dev-Mode rule, the Bash-vs-PowerShell note, the line-ending .gitattributes notes, and "Settings sync (hand-managed, by choice)."
  • Commit convention — change the line that endorses a "Co-Authored-By trailer" to the resolved rule: omit the Co-Authored-By trailer by default, always (including no Co-Authored-By: Claude); add one only when Brad explicitly asks in the moment. (This is the promoted memory fact, now global.)
  • .gitignore — reword the header comment "the personal/ subdirectory of the Seafile library" → "the claude-personal repo (a top-level peer under C:\Projects\)."

Done when: personal CLAUDE.md describes the flat layout and the omit-trailer rule; no Seafile as a live path/sync mechanism remains in either file. Confirm by: rg -i seafile claude-personal/CLAUDE.md claude-personal/.gitignore returns nothing; re-read the rewritten Machine-Setup subsections + the commit-convention line together.

Task 5: Repoint the yggdrasil path references

Touches: yggdrasil/AGENTS.md:162, yggdrasil/README.md:121, yggdrasil/skills/bookmarking/SKILL.md:36, yggdrasil/commands/scry.md:60, yggdrasil/.claude/settings.json:5-6.

Five targeted edits (all C:\Seafile\Claude\…C:\Projects\…, dropping the Claude\ segment):

  • AGENTS.md:162 — "symlinked from the Seafile library root" → "symlinked from claude-personal (a sibling repo under C:\Projects\)."
  • README.md:121 — "cloned to C:\Seafile\Claude\yggdrasil\" → "cloned to C:\Projects\yggdrasil\."
  • bookmarking/SKILL.md:36C:\Seafile\Claude\yggdrasil\bookmarks.mdC:\Projects\yggdrasil\bookmarks.md.
  • scry.md:60 — example path C:\Seafile\Claude\yggdrasil\.puppet\…C:\Projects\yggdrasil\.puppet\….
  • .claude/settings.json:5-6Write/Edit(//C/Seafile/Claude/yggdrasil/.puppet/**)…(//C/Projects/yggdrasil/.puppet/**).

Done when: none of the five files reference Seafile as a path. Confirm by: rg -i seafile yggdrasil/AGENTS.md yggdrasil/README.md yggdrasil/skills/bookmarking/SKILL.md yggdrasil/commands/scry.md yggdrasil/.claude/settings.json returns nothing.

Task 6: Create yggdrasil/CLAUDE.md

Touches: yggdrasil/CLAUDE.md (new, repo root).

Create a minimal repo-root CLAUDE.md carrying just the commit convention so it auto-loads when cwd is yggdrasil (the portability insurance — present even when the personal layer isn't wired). Content: the omit-Co-Authored-By-by-default rule (same as Task 4's, phrased standalone), with a one-line note that it's intentionally duplicated from personal CLAUDE.md for portability, and a pointer that this file is the seed of the future AGENTS.md→CLAUDE.md migration (bookmarked 2026-06-18).

Done when: yggdrasil/CLAUDE.md exists with the convention. Confirm by: the file exists and reads correctly together; it's a .md so the existing *.md text eol=lf .gitattributes already governs it (no extra step).

Task 7: Reconcile yggdrasil Seafile-referencing docs

Touches: yggdrasil/bookmarks.md and yggdrasil/working/host-relocation-design.md.

  • bookmarks.md:
    • L20 (the "Phase Seafile out" bookmark) — its doc-scrub to-do is being done by this work; update it to mark the scrub/relocation done, keeping the cloud-relocation remainder pointing at host-relocation-design.md. (Append a dated update, don't rewrite history.)
    • L15 — repoint the additionalDirectories example C:\\Seafile\\Claude\\yggdrasilC:\\Projects\\yggdrasil.
    • L35 / L36 — append a brief dated note: the bookend git worktree remove "Permission denied" race was attributed to Seafile scanning the tree; with Seafile uninstalled, watch whether it still recurs (the premise may no longer hold).
    • Fix the pre-existing newline mash between the 2026-06-09 (L36) and 2026-06-11 (Vrataski) entries so they're separate bullets.
  • host-relocation-design.md — light touch only: a dated note that the human-window viewer is now Kingdom.md (not Perlite/roll-your-own-TBD) and that single-machine is the interim reality (the multi-machine driver is gone for now). Leave the rest of the design intact — it stays the live cloud thread.

Done when: the Seafile-referencing bookmarks reflect post-retirement reality; the newline mash is fixed; host-relocation-design.md carries the viewer/interim note. Confirm by: re-read the four touched bookmark entries + the host-relocation note together; confirm no stale Seafile path references remain (topic-references in these entries are fine and expected).

Task 8: Memory triage (depends on Tasks 4 + 6 landing the convention)

Touches: ~/.claude/projects/C--Seafile-Claude-yggdrasil/memory/MEMORY.md and omit-claude-coauthor-trailer.md. Not in any repo (a live machine path; this edit is non-git).

Once the co-author convention is in both CLAUDE.md files (Tasks 4 + 6), retire it from memory:

  • Delete omit-claude-coauthor-trailer.md.
  • Update MEMORY.md — remove its index line; keep the git-commit-from-powershell.md line (that fact stays — it's machine/PowerShell-specific).
  • Leave git-commit-from-powershell.md untouched.

Done when: memory holds only the git-commit fact; MEMORY.md index matches. Confirm by: list the memory dir (expect MEMORY.md + git-commit-from-powershell.md, no co-author file); re-read MEMORY.md together.

Task 9: Build relocate-claude.ps1

Touches: C:\Install\Claude\relocate-claude.ps1 (run location) + a committed copy in yggdrasil/working/ (the migration artifact's record — keeps it with the design/plan).

Author the idempotent relocation script with a -DryRun switch. Ordered steps (full logic spelled out in the script):

  1. Preflight (abort with a clear message): the three source dirs present at C:\Seafile\Claude\ (or already moved → re-run detection); C:\Projects exists; no registered git worktrees in any repo (git -C <repo> worktree list shows only the main line); working trees committed.
  2. Move personalC:\Projects\claude-personal, yggdrasilC:\Projects\yggdrasil, odin-codinC:\Projects\odin-codin (skip any already at target).
  3. Migrate memorycopy (not move) each existing ~/.claude/projects/C--Seafile-Claude-*C--Projects-*, mapping the personal segment to claude-personal. Skip targets that exist.
  4. Pre-clean ~/.claude links — delete the skills/ and commands/ link-dirs and the CLAUDE.md link wholesale (clean slate; avoids broken-junction edge cases).
  5. Repoint live ~/.claude/settings.json — string-replace only the two hook command paths C:/Seafile/Claude/personal/hooks/C:/Projects/claude-personal/hooks/; leave all else (incl. GitKraken) untouched.
  6. Run C:\Projects\claude-personal\skills\new-machine-setup\relink.ps1 (rebuilds the links fresh).
  7. Invoke self-check-claude.ps1 and print its report. -DryRun prints every intended action and touches nothing.

Done when: the script exists in both locations and its logic matches the seven steps. Confirm by: structural re-read together, and run relocate-claude.ps1 -DryRun from this session — confirm it prints sensible planned actions and correctly reports the live session worktree as a preflight blocker (proving the preflight guard works; the real run happens post-disposal). Note: a non-dry run cannot be tested here (it would move the running directory).

Task 10: Build self-check-claude.ps1

Touches: C:\Install\Claude\self-check-claude.ps1 (run location) + a committed copy in yggdrasil/working/.

Author the independently-runnable verifier; PASS/FAIL per assertion:

  • The three targets exist + are git repos (.git present); the three C:\Seafile\Claude\ repo sources are gone.
  • ~/.claude/CLAUDE.md resolves to C:\Projects\claude-personal\CLAUDE.md and reads.
  • Every ~/.claude/skills/* junction and commands/* symlink targets C:\Projects\*zero still pointing at C:\Seafile; counts sane.
  • Live settings.json hook paths point at C:\Projects\claude-personal\hooks\ and those .ps1 files exist.
  • Memory dir present at C--Projects-yggdrasil.
  • Residual-path grep: no C:\Seafile path in operational files (scripts, settings.json, skill/command instructions, configs), excluding the two design docs, archive/*, dated current-plan.md checkpoints, and retirement-narrating bookmarks (topic-references, not paths).

Done when: the script exists in both locations with all assertions. Confirm by: structural re-read together, and run self-check-claude.ps1 now — confirm it correctly reports the pre-move state (sources present, targets absent → expected FAILs), proving the checks are wired right and just reporting "not done yet."


Phase B — the handoff (Brad runs after the session closes; documented, not walked here)

This phase is not a task we execute together in-session — it's the procedure Brad runs solo after /save-progress disposes the worktree and the session closes. Recorded here as the gate.

  1. /save-progress — pin the checkpoint and dispose the session worktree (merge to main). Close the session.
  2. From C:\Install\Claude: .\relocate-claude.ps1 -DryRun → eyeball the plan.
  3. .\relocate-claude.ps1 → move + migrate memory + repoint settings + pre-clean/relink + auto-run self-check.
  4. Open a fresh session at C:\Projects\yggdrasil; confirm self-check-claude.ps1 reads all PASS.
  5. Delete the inert C:\Seafile\Claude\ by hand once satisfied (the rollback path until then).

The self-check reading all-PASS in step 4 is the plan's overall verification gate.


Deferred

  • 2026-06-18GitHub private remotes for all three repos (the off-machine backup that replaces Seafile's role). Trigger: right after the relocation completes and the self-check passes — Brad flagged it as the near-term next effort. Closes the brief single-copy-local gap and lays the cloud-move foundation.
  • 2026-06-18General /hygiene-check bookmark-curation pass. Trigger: at/after session end, once the Seafile edits settle. Distinct from Task 7's targeted Seafile-reference reconciliation — this is the broader list-curation sweep Brad slated for the end.
  • 2026-06-18relink.ps1 broken-reparse-point hardening (Task 1's optional bit). Trigger: if relink.ps1 is ever re-run outside the relocate script's pre-clean and trips over a stale junction. Not needed for this move.