Normalize markdown formatting after the latest main updates.\n\nChecks: python3 scripts/layered_soul.py validate .; npx --yes prettier@3 --check '**/*.md'; git diff --check.
3.1 KiB
Codeberg → Self-Hosted Forgejo Migration Plan
Target: code.smilepowered.org (Forgejo 10.0.3, port 2222 SSH)
Architecture: Machine-User Model
Each host/agent gets its own Forgejo user + SSH key + scoped token for clean audit trails and per-agent revocation:
| User | Host | Agent | Access |
|---|---|---|---|
| clawdie | — | Org owner | Admin (bootstrap only) |
| hermes-debby | debby | Hermes | write:repository |
| claude-domedog | domedog | Claude | write:repository |
| codex-osa | osa | Codex | read:repository (initially) |
Principle: never copy private SSH keys between hosts. Each machine user gets its own key generated on that host.
Migration Order
- Create repos under
clawdieuser (org creation blocked — user/org name collision; repos under user account have identical URL structure)- clawdie/colibri, clawdie/clawdie-ai, clawdie/clawdie-iso
- Push Colibri first (smoke test — 300 KB, instant)
- Push Clawdie-AI (187 MB, 1636 commits — background push, ~5 min)
- Push Clawdie-ISO from cleaned mirror
- Verify all three repos with
git ls-remoteand Forgejo API - Update AGENTS.md in each repo: replace Codeberg remotes with Forgejo
- Create per-agent machine users + SSH keys
- Add branch protection after initial imports succeed
- Add webhooks/CI-style FreeBSD validation
- Delete bootstrap admin token
Token Strategy
- One bootstrap token with write:repository + write:user + write:organization for setup only
- Revoke bootstrap token after setup complete
- Each machine user gets its own scoped token
- Day-to-day git operations use SSH keys, not tokens
- Tokens are immutable after creation — to change scopes, delete and recreate
SSH Pitfall: Password Popups from Agent Tools
When an agent tool (non-TTY) runs ssh to a host where the key isn't authorized, KDE's ssh-askpass fires a graphical password prompt on the user's desktop. Prevention: test SSH access manually from a real terminal before delegating to agent tools. Ensure IdentitiesOnly yes + PreferredAuthentications publickey in SSH config.
Shallow Clone Fixes
When pushing a shallow clone to Forgejo fails with "shallow update not allowed" and the original remote is unreachable:
- Check
.git/shallowfor boundary commits - Create a graft making the root commit parentless:
echo "$(cat .git/shallow) " > .git/info/grafts git filter-branch -f --msg-filter "cat" -- --all rm .git/info/grafts .git/shallow - Push — repo is now self-contained
WARNING: rewrites commit hashes. Only for migration when original remote history is preserved elsewhere.
Verification After Push
git ls-remote git@code.smilepowered.org:clawdie/$REPO.git HEAD
curl -s "https://code.smilepowered.org/api/v1/repos/clawdie/$REPO" \
-H "Authorization: token <token>" | \
python3 -c "import sys,json; d=json.load(sys.stdin); \
print(f'HEAD: {d[\"default_branch\"]} Size: {d[\"size\"]} KB Empty: {d[\"empty\"]}')"