Hardware: Lenovo ThinkPad X1 2-in-1 Gen 9, Intel Core Ultra 7 155U, 16GB RAM, 512GB SSD Scope: Full CCO (Claude Code + Obsidian with ~/Files as vault root) Timezone: Australia/Adelaide (local) Backup: Obsidian Sync ($4/month) Remote support: None initially (can add Tailscale later if needed)

Encryption: Yes (LUKS) - enter passphrase each boot


Pre-Setup Checklist

  • Kubuntu 25.10 USB installer (get from https://kubuntu.org/getkubuntu/)
  • Verify ISO with Claude Code on Windows: ask it to verify sha256sum matches website
  • 1Password account (or create one during setup)

Phase 1: OS Installation

BIOS Setup

  1. Boot to BIOS (F2 or F12 on ThinkPads)
  2. Disable Secure Boot
  3. Set USB as first boot device
  4. Save and exit

Install Kubuntu

  1. Boot from USB โ†’ “Install Kubuntu”
  2. Language: English (Australia)
  3. Keyboard: US (or your preference)
  4. Select “Normal installation”
  5. Enable “Download updates while installing”
  6. Enable “Install third-party software”
  7. Partitioning: “Erase disk and install Kubuntu”
  8. Check “Encrypt the new Kubuntu installation” โ†’ set strong passphrase (4+ random words or 16+ characters)
    • Critical: Store this passphrase in 1Password BEFORE rebooting. If you forget it, your data is permanently unrecoverable.
    • This passphrase is entered at every boot, before the login screen appears.
  9. Timezone: Australia/Adelaide
  10. Create user account (lowercase username, no spaces)
  11. Wait ~15-20 min
  12. Reboot, remove USB

First Boot

  1. Connect to WiFi (click network icon in system tray)
    • If WiFi networks don’t appear, connect via USB ethernet adapter or phone USB tethering, then ask Claude Code to troubleshoot WiFi after Phase 3
  2. Open Konsole (terminal): click the application launcher (bottom-left or press Meta/Windows key) and type “Konsole”
  3. Run:
sudo apt update && sudo apt full-upgrade -y
  1. Reboot if you see “linux-image” in the upgrade list

Phase 2: Core System Setup

Remove Snap

Snap is Ubuntu’s app packaging system. We use Flatpak instead (better sandboxing, less bloat).

# Remove all snaps (may take a few attempts as dependencies resolve)
while snap list 2>/dev/null | grep -v "^Name" | grep -q .; do
    snap list | tail -n +2 | awk '{print $1}' | xargs -I {} sudo snap remove --purge {} 2>/dev/null
done

# Remove snapd itself and prevent reinstall
sudo apt remove --purge snapd -y
sudo apt-mark hold snapd

# Clean up leftover directories
rm -rf ~/snap
sudo rm -rf /var/snap /var/lib/snapd

Install Core Packages

# Essential CLI tools
sudo apt install -y git curl wget build-essential htop neovim \
    flatpak plasma-discover-backend-flatpak

# Add Flathub (the main Flatpak app repository)
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo

Flatpak is an app packaging system (like Snap but better). Flathub is where Flatpak apps are downloaded from.

Install GUI Apps

flatpak install -y flathub com.brave.Browser
flatpak install -y flathub org.mozilla.firefox
flatpak install -y flathub md.obsidian.Obsidian

# 1Password - NOT on Flathub, uses its own repo
flatpak install -y https://downloads.1password.com/linux/flatpak/1Password.flatpakref

Install Node.js & Claude Code

# Node.js 22.x LTS
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs

# Claude Code
sudo npm install -g @anthropic-ai/claude-code

# Verify installation
node --version   # Should show v22.x.x
claude --version # Should show version number

WezTerm Terminal (Optional)

GPU-accelerated terminal with better font rendering than Konsole.

# Add WezTerm apt repository
sudo mkdir -p /usr/share/keyrings
curl -fsSL https://apt.fury.io/wez/gpg.key | sudo gpg --yes --dearmor -o /usr/share/keyrings/wezterm-fury.gpg
sudo chmod 644 /usr/share/keyrings/wezterm-fury.gpg
echo 'deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *' | sudo tee /etc/apt/sources.list.d/wezterm.list

# Install WezTerm and font
sudo apt update && sudo apt install -y wezterm fonts-jetbrains-mono

# Configure WezTerm
mkdir -p ~/.config/wezterm
cat > ~/.config/wezterm/wezterm.lua << 'EOF'
local wezterm = require 'wezterm'
local config = {}

config.color_scheme = 'Catppuccin Mocha'
config.font = wezterm.font 'JetBrains Mono'
config.font_size = 12.0
config.scrollback_lines = 10000
config.enable_scroll_bar = false

-- Browser-like keybindings
config.keys = {
    { key = 't', mods = 'CTRL', action = wezterm.action.SpawnTab 'CurrentPaneDomain' },
    { key = 'w', mods = 'CTRL', action = wezterm.action.CloseCurrentTab { confirm = true } },
}

-- Tab switching with Ctrl+1-9
for i = 1, 9 do
    table.insert(config.keys, { key = tostring(i), mods = 'CTRL', action = wezterm.action.ActivateTab(i - 1) })
end

return config
EOF

If the apt repository fails (401 error), download the .deb from https://github.com/wezterm/wezterm/releases instead.

Hardware Check

Test a reboot now. Normal shutdown takes under 30 seconds. If it hangs for several minutes, note the issue - we’ll fix it with Claude Code in Phase 3.


Phase 3: Claude Code + Obsidian Setup

Clone Template

The template contains:

  • NIPARAS folder structure: Now (today’s focus), Inbox (unsorted captures), Projects (time-bound goals), Areas (ongoing responsibilities), Resources (reference material), Archive (completed/inactive), System (configuration)
  • Claude Code commands: /park saves session context, /pickup resumes where you left off, /morning and /goodnight for daily routines
git clone https://github.com/OpenCairn/OpenCairn.git ~/Files
cd ~/Files
git remote rename origin template
chmod +x .claude/scripts/*.sh

Verify the commands are in place:

ls ~/Files/.claude/commands/
# Should show: park.md, pickup.md, morning.md, goodnight.md, etc.

Configure Environment

cat >> ~/.bashrc << 'BASHEOF'

# CCO: vault path (required by template scripts)
export VAULT_PATH="$HOME/Files"

# CCO: launch Claude Code from vault root
alias cc='cd ~/Files && claude'
BASHEOF
source ~/.bashrc

First Claude Code Session

Before starting: Open 1Password and sign in - you’ll need access to any passwords for authentication.

cd ~/Files
claude
# Follow authentication prompts (Google, GitHub, or email)
# Success: You'll see a ">" prompt ready for input
# If auth fails: try "claude logout" then "claude" again

Once authenticated, prompt Claude Code:

“I just set up this laptop with the CCO template. My vault is at ~/Files. Help me:

  1. Remap my XDG directories (Downloads, Documents, etc.) to use the NIPARAS folders in ~/Files
  2. Configure Dolphin file manager sidebar with the NIPARAS folders in ~/Files
  3. Set WezTerm as my default terminal (if I installed it)
  4. Fix any Bluetooth shutdown hang issues from Phase 2
  5. Customise CLAUDE.md with my personal context”

Claude Code will handle the system configuration and walk you through personalising your setup interactively.


Phase 4: Obsidian Sync Setup

  1. Open Obsidian

  2. Open vault at ~/Files

  3. Settings โ†’ Sync โ†’ Subscribe ($4/month)

  4. Create remote vault with E2E encryption password (store in 1Password!)

  5. Critical exclusions (Settings โ†’ Sync โ†’ Excluded folders):

    • .git
    • .claude
  6. On your phone: Install Obsidian โ†’ Connect to same remote vault

Restic + Backblaze B2 (Optional)

Versioned offsite backup in addition to Obsidian Sync. Costs ~$6 USD/month.

Setup steps:

  1. Create Backblaze B2 account at https://www.backblaze.com/b2/
  2. Create a bucket and application key
  3. Ask Claude Code: “Help me set up restic backup to Backblaze B2” - it will create the config files and systemd timer for automated daily backups

Or do it manually:

Security note: The credentials file below contains your B2 API key and backup encryption password in plaintext. Keep these values in 1Password as the authoritative source - the file is just for automation.

# Install restic
sudo apt install -y restic

# Create config directory
mkdir -p ~/.config/restic

# Create credentials file (fill in your B2 details)
cat > ~/.config/restic/env << 'EOF'
export B2_ACCOUNT_ID="your-key-id"
export B2_ACCOUNT_KEY="your-application-key"
export RESTIC_REPOSITORY="b2:your-bucket-name:backups"
export RESTIC_PASSWORD="your-restic-password"
EOF
chmod 600 ~/.config/restic/env

# Create exclusions file
cat > ~/.config/restic/excludes.txt << 'EOF'
.cache
.local/share/Trash
.npm
.nvm
.gnupg
.pki
.mozilla
.ssh
node_modules
*.log
Cache
.var
EOF

# Create backup script with error handling
cat > ~/.config/restic/backup.sh << 'EOF'
#!/bin/bash
set -e
source ~/.config/restic/env
restic backup ~ --exclude-file="$HOME/.config/restic/excludes.txt" || exit 1
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
EOF
chmod +x ~/.config/restic/backup.sh

# Initialise repo (first time only)
source ~/.config/restic/env
restic init

# Test backup
~/.config/restic/backup.sh

Phase 5: Auto-Maintenance

Flatpak Auto-Updates

mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/flatpak-update.service << 'EOF'
[Unit]
Description=Update Flatpak apps

[Service]
Type=oneshot
ExecStart=/usr/bin/flatpak update -y --noninteractive
EOF

cat > ~/.config/systemd/user/flatpak-update.timer << 'EOF'
[Unit]
Description=Daily Flatpak update

[Timer]
OnCalendar=*-*-* 20:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

systemctl --user daemon-reload
systemctl --user enable --now flatpak-update.timer

APT Auto-Updates

sudo tee /etc/systemd/system/apt-full-upgrade.service << 'EOF'
[Unit]
Description=APT full upgrade

[Service]
Type=oneshot
ExecStart=/usr/bin/apt update
ExecStart=/usr/bin/apt full-upgrade -y
EOF

sudo tee /etc/systemd/system/apt-full-upgrade.timer << 'EOF'
[Unit]
Description=Daily APT upgrade

[Timer]
OnCalendar=*-*-* 20:00:00
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now apt-full-upgrade.timer

Autotrash

# Install pipx and autotrash
sudo apt install -y pipx
pipx ensurepath
export PATH="$PATH:$HOME/.local/bin"  # Make pipx available immediately
pipx install autotrash

# Install systemd timer (auto-deletes files in trash older than 10 days)
autotrash --install -d 10

Phase 6: Verification

System

  • Reboot - system shuts down cleanly (no hang)
  • WiFi reconnects after reboot
  • Disk encryption passphrase works

Apps

  • Brave opens and browses
  • Obsidian opens vault at ~/Files
  • Claude Code starts with cc command
  • 1Password unlocks

Workflow

  • Claude Code commands work - try /park
  • Obsidian Sync working - changes appear on phone

Git Config (Optional)

Only needed if you’ll use git for your own projects. The template clone doesn’t require it.

git config --global user.name "Your Name"
git config --global user.email "your@email.com"

If You Get Stuck

  1. Ask Claude Code - it can troubleshoot most Linux issues
  2. Message Harrison - can set up Tailscale for remote SSH support if needed