A Claude Code skill (/coredesktop-pop-merge) with the plan for folding connector-popos, the Pop!_OS port of configure, back in here behind a platform layer, so one Linux configure runs on Arch and Pop!_OS. It records the facts verified while porting and the decisions still open, so the work can be picked up later. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
14 KiB
name, description
| name | description |
|---|---|
| coredesktop-pop-merge | Plan and progress for merging Pop!_OS support (the connector-popos port) into CoreDesktop's configure, so one Linux configure runs on Arch and Pop!_OS with COSMIC. Use when resuming, continuing, checking the status of, or changing the Pop!_OS/CoreDesktop merge, the platform layer (configure.d/lib/platform.sh), or connector-popos. |
Merge Pop!_OS support into CoreDesktop's configure
Where things stand
Work out the current state before doing anything; this plan was written on 2026-11-11 and may be partly done:
git -C ~/Projects/coredesktop fetch && git -C ~/Projects/coredesktop log --oneline origin/main -20
ls ~/Projects/coredesktop/configure.d/lib/platform.sh ~/Projects/coredesktop/pop 2>/dev/null
git -C ~/Projects/connector-popos log --oneline -5
curl -s -o /dev/null -A curl/8 -w '%{redirect_url}\n' https://federated.sh/pop
Map what you find onto the steps below, tell the user which step is next, and confirm before starting it.
Repositories
| Repo | Local | What |
|---|---|---|
Federated_Computer/coredesktop |
~/Projects/coredesktop |
Arch + GNOME desktop setup; configure and configure.d/ are one part of it |
Federated_Computer/connector-popos |
~/Projects/connector-popos |
Standalone Pop!_OS port of configure, published 2026-11-11 (commit bc07e1d, MIT). To be archived after the merge. |
Federated_Computer/connector-macos |
~/Projects/connector-macos |
macOS port. Stays separate: bash 3.2, no jq/python, profiles, launchd, Seatbelt. |
All on https://gitea.federated.computer. Pushing uses the cached git credentials. git's credential cache socket is blocked inside Claude Code's sandbox, so git push needs the sandbox turned off for that command.
Why merge
connector-popos is a fork, not a port. Measured against CoreDesktop: 10-core 92% unchanged, storage 93%, ai-servers 95%, sandbox item 97%, and goa-account, email-watch, setup-printers.sh, nextcloud.sh, mdns.sh and json.sh 94–100%. CoreDesktop's configure is changing fast (12+ commits since late October), so a fork drifts. That already happened twice: the step name clash (fixed in connector-macos, not CoreDesktop), and the Online Accounts 3.50 attention fix (only in connector-popos). macOS shares little code (10-core 37%, mdns 27%) and stays separate.
Facts verified while porting (don't re-derive)
- Pop!_OS:
- 24.04 LTS with COSMIC, released 2025-12-11; 26.04 was still unreleased in August 2026.
- Pop's apt repo has cosmic-files 1.11.
- pop-desktop/cosmic-session pull in gnome-keyring and libsecret, but not gnome-online-accounts or Evolution.
- GOA, davfs2, restic, rclone and the rest come from Ubuntu noble.
- COSMIC has no Online Accounts. The user chose GNOME Online Accounts + Evolution, with configure adding accounts through
goa-accountexactly as on Arch. Thunderbird was rejected, because the password-changed flow and the email watcher can't be ported to it. - GOA 3.50 (Ubuntu noble) works headless with
goa-account: add, exists, pause/paused, update, check, remove and disabled all pass. But it setsAttentionNeeded(NotAuthorized) for unreachable servers too, for both Nextcloud and mail. So "needs attention" must not be read as "wrong password". The email watcher is already safe: it confirms with Nextcloud, and skips when Nextcloud can't be reached. - COSMIC session:
cosmic-session.targetbindsgraphical-session.targetand wantsxdg-desktop-autostart.target, so user units withWantedBy=graphical-session.targetand XDG autostart entries both work.- cosmic-notifications supports
notify-send --action. cosmic-term -e <cmd...>runs a command.
- COSMIC Files sidebar:
- cosmic-config
~/.config/cosmic/com.system76.CosmicFiles/v1/favorites, a RON list ofHome|Documents|Downloads|Music|Pictures|Videos|Path("..")|Network(uri:,name:,path:)|Named(path:,name:). Namedexists since epoch 1.7.- If the file is missing, cosmic-files uses the six defaults, so write those first.
- Helper:
connector-popos/configure.d/lib/cosmic-favorites.
- cosmic-config
- davfs2 on Ubuntu:
- User mounts need
mount.davfssetuid. Set it withecho "davfs2 davfs2/suid_file boolean true" | sudo debconf-set-selections, before install, or followed bydpkg-reconfigure -f noninteractive davfs2. - The group is
davfs2; Arch usesnetwork.
- User mounts need
- Ubuntu noble's versions: restic 0.16.4 and rclone 1.60.1, enough for
rclone::webdav:andrclone obscure -. Pop's Node.js is too old for srt (needs 22.12+), so download the LTS from nodejs.org, checking SHASUMS256. Current Node (v26) needslibatomic1. - The sandbox on Ubuntu 24.04: bubblewrap may be blocked by
kernel.apparmor_restrict_unprivileged_userns=1. The fix is an AppArmor profile for/usr/bin/bwrapwithuserns,. It's unverified whether Pop sets this; check on a real machine. - Package paths: Ubuntu's libnss-mdns uses
mdns4_minimal, notmdns_minimal. GTK's CUPS backend is at/usr/lib/*/gtk-3.0/*/printbackends/libprintbackend-cups.so.fusermount3is in/usr/bin. The keyring's SSH agent is at$XDG_RUNTIME_DIR/keyring/ssh, orgcr/ssh. - Installers: Tailscale's
install.shhandlesID=pop. mise's apt repo ishttps://mise.jdx.dev/deb stable main, with the key athttps://mise.jdx.dev/gpg-key.pub. - federated.sh is Caddy. Its
/macrule:- matches case-insensitively, with or without a trailing slash, ignoring the query; paths below it fall through
- sends a User-Agent starting with
Mozillato the repo page, and everything else to the rawinstall.sh /popdidn't exist on 2026-11-11 (it fell through to CoreDesktop's Arch installer); a Caddy skill to add it was handed to the server's agent, pointing at connector-popos
Decisions (defaults; the user can change them)
- Pop uses CoreDesktop's names:
~/.local/share/coredesktop,~/.config/coredesktop,coredesktop-*units,coredesktop backupkeyring attributes,/etc/coredesktop/smb. Arch users then need no migration. connector-popos usedfederated-connector-*names, so anyone who installed it needs a one-time migration, or a reinstall. - Pop installs with git, cloning into
~/.local/share/coredesktop, soupdateis agit pull. This replaces connector-popos' tarball swap. - Pop gets its own
pop/update: pull, reinstall the commands, refresh the user units, restart the email watcher, and run migrations marked for Pop. CoreDesktop'supdateruns Arch-only hooks; Pop's own updater handles the system. - Items install what's missing, with
pkg_ensure. On Arch everything is there, so this does nothing. - Hold the federated.sh/pop switch until step 6, or add a migration from connector-popos' paths.
Still open; ask the user:
- Has CoreDesktop's owner signed off? The merge touches
configurewhile it's being actively changed. - Branding on Pop: should users see "CoreDesktop" or "Federated Connector"?
Design: configure.d/lib/platform.sh
configure sources it; it sets PLATFORM=arch|pop from /etc/os-release. An Ubuntu-like system counts as pop, with a "made for Pop!_OS" warning. It provides:
-
pkg_installed,pkg_ensure <why> <pkg>...andpkg_install: pacman on Arch, dpkg/apt on Pop. They take Pop's (Debian) names, with a table of Arch names:Pop Arch avahi-utilsavahilibsecret-toolslibsecretlibatomic1gcc-libspython3-gipython-gobjectgir1.2-secret-1libsecretlibnotify-binlibnotifysmbclientsmbclient -
flatpak_installedandflatpak_ensure. -
sidebar_add,sidebar_removeandsidebar_has. Both platforms write GTK bookmarks; Pop also writes COSMIC Files' favorites. -
DAVFS_GROUP(networkordavfs2) anddavfs2_ready(setuid through debconf on Pop; nothing on Arch). -
element_installedandelement_config: theim.riot.RiotFlatpak keeps it at~/.var/app/im.riot.Riot/config/Element/config.json, otherwise~/.config/Element/config.json. -
goa_readyand the accounts text: "Online Accounts (Settings)" on Arch, "shown in Evolution" on Pop, which also installs gnome-online-accounts, evolution, python3-gi and gir1.2-secret-1. -
install_tailscale: pacman, or Tailscale'sinstall.sh, downloaded then run. -
install_miseandmise_activated: on Arch, mise comes from pacman andshell/bashrcactivates it; on Pop, mise's apt repo and a block in~/.bashrc.
Done in place, not through the layer:
system/run-in-terminaltriescosmic-term -efirst.system/sftp-mountalso trieskeyring/ssh.setup-printers.shchecks dependencies and GTK's backend per platform, and acceptsmdns4_minimal.
Steps (one reviewable PR each)
1. Platform layer, Arch unchanged (pure refactor)
- Add
platform.shwith the Arch side only. - Change
10-core.sh,15-tailscale.sh,20-backup.sh,40-languages.sh,60-storage.sh(sudo pacman -S sshfsbecomespkg_ensure) andsetup-printers.shto call it. - Drop the
is_installedchecks that only hid an item when its tools were missing (backup, ai-servers, printers, storage, tailscale); the item now offers to install them. - Tests:
- bats tests for
platform.sh, stubbing pacman, dpkg and apt astests/test_helper.bashalready does make lint,bats tests- CoreDesktop's VM smoketest quick tier (
coredesktop-dev smoketest run, through the coredesktop-dev sibling), to show Arch is unchanged
- bats tests for
2. Fixes for both platforms
test_accountin10-core.sh:- drop the
"$GOA_ACCOUNT" attentionbranch - keep
email-watch --check-password(Nextcloud) beforegoa-account check - update the comment: 3.50 flags unreachable servers. On Arch's 3.58 this only adds one Nextcloud sign-in during Test a Core.
- drop the
- Rename
steptocore_stepin10-core.sh, including the[ ... ] && step element|tallylines. - Comment fixes: the 3.58 notes in
configure.d/lib/goa-accountandsystem/email-watch.
3. Pop's side of the layer
- Fill in
platform.shfor Pop. - Copy from connector-popos:
configure.d/lib/cosmic-favorites- the davfs2 setuid step
- the Tailscale and mise apt-repo installs
- the Element Flatpak path
configure: a menu title and the not-Pop warning per platform; refuse to run as root.- Docs: what's different on Pop (Evolution, COSMIC Files, AppArmor) and what needs a real Pop machine.
- connector-popos' README "Differences from CoreDesktop" lists everything this step must cover.
4. The agents item, sharing the sandbox setup
- Move
sandbox/setup.sh's logic into functions insandbox/lib.sh, used by bothsetup.sh(Arch,updates.d/72-sandbox.sh) and a newconfigure.d/30-agents.sh(fromconnector-popos/configure.d/30-agents.sh):- Claude Code's sandbox defaults, plus
claude.sh's notification hooks - the Hermes gateway drop-in (keep the name
coredesktop-sandbox.conf) - the Cline Desktop entry
- Claude Code's sandbox defaults, plus
- Renumber
30-claude,31-opencodeand32-hermesto31,32and33. Item names don't change. 30-agentson Arch: shows done.30-agentson Pop: installs the agents with their own installers, installs Node.js and srt under~/.local/share/coredesktop/tools(lib/tools.sh), addslibatomic1, the PATH block and the AppArmor offer.srt_pathfinds~/.local/bin/srt(Arch's npm install) or the tools one.sandbox/agentusesagent_path(connector-poposconfigure.d/lib/agents.sh).sandbox/config/base.json: addubuntu.com,*.ubuntu.com,pop-os.org,*.pop-os.org,system76.comand*.system76.comnext to Arch's, and~/.config/evolution,~/.local/share/evolution,~/.cache/evolution,~/.config/goa-1.0and~/.thunderbirdtodenyRead.
5. Installing and updating on Pop
pop/install.sh: adapt fromconnector-popos/install.sh.- preflight: apt, not root, sudo group, network
apt install git curl jq libsecret-tools python3-gi gir1.2-secret-1 libnotify-bin- clone,
install_scriptforconfigureandpop/updateinto~/.local/bin - put
~/.local/binon PATH at the top of~/.bashrc - mark the existing migrations as done
- offer configure, reading answers from
/dev/ttyand apt's stdin from/dev/null
pop/update:git pull --ff-only, reinstall the commands, refresh thecoredesktop-*units configure installed, restart the email watcher, run Pop migrations.- Migrations:
run_migrations(utils.sh) runs only those whose header has# platforms:naming the current platform; unmarked ones are Arch only. Check it doesn't pull in Arch-only parts ofutils.sh; if it does, move it tolib/migrations.sh. - Tests: move
connector-popos/smoketest/tosmoketest/pop/, rename the paths and units, and add it andbats teststo.gitea/workflows(the runner isubuntu-latest).
6. Switch over
- After a manual pass on a real Pop!_OS 24.04 machine (below), point federated.sh/pop at
https://gitea.federated.computer/Federated_Computer/coredesktop/raw/branch/main/pop/install.sh, with the browser redirect going to the repo page. That's a change to the Caddy skill's two targets. - Archive connector-popos, with a README pointer.
Verification
make lintandbats testson every PR.- The Arch VM smoketest after steps 1, 2 and 4.
- The Pop Docker smoketest (
smoketest/pop/run --tier all) after steps 3–5. Docker needs the sandbox turned off for that command. Its scenarios:- install and update
- the menu
- GOA 3.50
- Superpanel, Element, the sidebar, davfs2's secret
- restic and rclone against a local
rclone serve webdav - the srt sandbox,
--privileged - davfs2 setuid, sshfs, GTK print backend, mise
- Manual, on real Pop!_OS, which containers can't check:
- COSMIC Files showing the sidebar entries
- Evolution against a real Core
- the davfs2 mount after logging out and in
- the backup timer and the email watcher's notification, which opens
configure corein COSMIC Terminal - Tailscale with a Core's headscale
- real SMB and SFTP mounts
- whether the AppArmor profile is needed
Risks
- Arch regressions: step 1 changes no behavior and is checked on the VM first.
- Collisions with ongoing configure work: land steps 1–2 quickly, and tell contributors that new item code should go through
platform.sh. updatemeans different commands on Arch and Pop. Document both.
Effort
About 1.5–2 days:
- steps 1–2: half a day
- steps 3–4: half a day to a day
- step 5: half a day
- step 6 and the manual pass: an hour or two, plus a Pop machine