calendar and contacts are core again, with radicale as a plain sidecar

Reverses the 2026-08-13 decision to make caldav an app-store entry. Three
reasons it does not belong there.

It is not an integration. Photos-via-Immich or torrents-via-Transmission assume
you already run the thing; a calendar assumes nothing, and a personal server
without one is missing a baseline rather than an optional app.

It needs TWO top-level routes, /calendar and /contacts, and a plugin gets one —
derived from its appName, which is what makes it structurally impossible for a
plugin to shadow a core route. Nobody thinks "I'll open my dav", so collapsing
them under /dav was the wrong trade, and weakening the namespace guarantee to
allow two was a worse one. As core routes the question does not arise.

And it never actually needed Docker. Radicale is a ~2MB Python package;
sidecar/caldav/radicale.ts already spawns it directly on loopback with
http_x_remote_user. The container came from the app store making everything a
container, not from anything Radicale requires.

So: the routers are mounted again (/caldav for the UI's JSON door, /dav for app
passwords, the top-level /dav sync door and the two .well-known redirects),
officer-caldav joins CORE_PROCESSES, radicale joins the machine-setup package
list for all four package managers, and the catalogue entry is gone.

members.test.ts re-anchored a fifth time — caldav was one of two `accounts`
services and memos is now the last. Noted in the test that the sixth time
should be a literal fixture instead.

Verified: assertPermissionTotality accepts /caldav and /dav, tsgo clean,
1085 pass. NOT yet verified against a real client — radicale is not installed
on this machine.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 04:19:50 +00:00
co-authored by Claude Opus 5
parent f566fda0b2
commit 9c309c5ab6
7 changed files with 32 additions and 41 deletions
+4 -4
View File
@@ -103,23 +103,23 @@ pkgs_core() {
echo curl ca-certificates gnupg git jq unzip \
apt-transport-https lsb-release software-properties-common \
wget zip brotli build-essential python3 btop htop tree tmux ripgrep fd-find net-tools eza \
poppler-utils fail2ban unattended-upgrades
poppler-utils radicale fail2ban unattended-upgrades
;;
pacman)
echo curl ca-certificates gnupg git jq unzip \
wget zip brotli base-devel python btop htop tree tmux ripgrep fd net-tools eza \
poppler fail2ban
poppler radicale fail2ban
;;
dnf)
echo curl ca-certificates gnupg2 git jq unzip \
wget zip brotli python3 btop htop tree tmux ripgrep fd-find net-tools eza \
poppler-utils fail2ban
poppler-utils radicale fail2ban
;;
brew)
# curl, unzip and the TLS roots ship with macOS; the compilers come from
# the Xcode command line tools, which is not a formula — see xcode_clt_*.
# brotli is here because macOS ships the library but not the CLI.
echo gnupg git jq wget brotli btop htop tree ripgrep fd eza poppler
echo gnupg git jq wget brotli btop htop tree ripgrep fd eza poppler radicale
;;
esac
}