ThinkPad T16g Environment Restoration

Project Summary

Field Value

PRJ ID

PRJ-2026-04-p16g-deploy

Owner

Evan Rosado

Priority

P0

Category

Workstation Deployment

Status

Operational — Phases 0-8b complete, Phases 9-13 in progress

Hardware

ThinkPad P16g Gen 3 Intel (21V50016US)

Hostname

modestus-p16g (corrected from modestus-t16g during deployment)

Specs

Core Ultra 9 275HX, RTX 5090 24GB GDDR7, 64GB DDR5, 2TB Gen5 NVMe, 16" 3.2K Tandem OLED

Purpose

Portable workstation for client sites, travel. Identical AI/dev stack to Razer.

Cost

$4,226.98 (41% off MSRP)

Deployed

2026-04-02

Deployment Status

Phase Description Status Notes

0: Pre-Arrival

Borg backup, USB prep, gopass sync

✅ Done

Borg via NFS mount (not SSH). Ventoy not installed (AUR) — used dd.

1: Remote Access

Boot USB, iPSK MAC registration, WiFi, SSH from Razer

✅ Done

iPSK via DOMUS-IoT group. ISE verified with netapi + DataConnect.

2: Disk & Encryption

4-partition dual-LUKS, btrfs subvolumes, mount

✅ Done

ext4 XBOOTLDR failed — kernels on ESP instead. efi/ dir must be created after /boot mount.

3: Base System

pacstrap, fstab, chroot, crypttab, hostname, zram, users

✅ Done

UUID variable pattern for crypttab. sed verify-before/apply/verify-after for locale + sudoers.

4: Bootloader

mkinitcpio, systemd-boot, boot entries, reboot

✅ Done

Fallback presets commented out by default. Boot entries + kernels on ESP (VFAT). efibootmgr required for ThinkPad. ACPI GPE6E interrupt storm — masked with acpi_mask_gpe=0x6E.

5: First Boot

SSH reconnect, pacman -Syu, yay, multilib, packages

✅ Done

6: Desktop

NVIDIA, Hyprland, fonts, audio, bluetooth, themes, TLP

✅ Done

nvidia-open (not nvidia) for RTX 5090. ESP kernel sync + pacman hook. env-gpu.conf per-host symlink.

7: Dotfiles & Stow

Secrets bootstrap, rsync, dots-quantum, stow, domus-nvim, pinentry-auto

✅ Done

rsync with -F /dev/null (bypass Razer SSH config). GPG lock cleanup. gopass root store path fix. NVIM_APPNAME=nvim-domus → symlink to ~/.config/nvim-domus. Private packages (gpg/hosts/secrets) rsync’d separately. pinentry-auto for SSH vs desktop GPG prompts. kguiaddons + kwindowsystem for pinentry-qt. gpg-connect-agent updatestartuptty in .zshrc for SSH sessions. 37 of 44 packages stowed. env-gpu.conf per-host symlink (gitignored). gocryptfs gcvault deployed with 4 encrypted vaults. Stow audit script documented.

8: Secrets

age, SSH keys, gopass, gocryptfs vault, Vault SSH

✅ Done

Keys rsync’d, gopass working with pinentry-auto. gocryptfs vault deployed (gcvault mount credentials). Claude Code + gh CLI symlinked to vault. SSH config re-encrypted with modestus-p16g entry and corrected Razer IP. Vault SSH certs for machine-to-machine blocked by VLAN segmentation (anti-pivot) — deferred.

8b: EAP-TLS

Vault cert, nmcli WiFi EAP-TLS

✅ Done

WiFi EAP-TLS on DOMUS-Secure VLAN (10.50.10.x). Cert re-issued with CN=modestus-p16g (Apr 3). Cert workflow: ds d000 dev/vaultvault write | tee | jq → extract → verify → install → nmcli modify. Wired EAP-TLS deferred (no cable yet).

9: Development

Languages, repo clones, multi-remote, Claude Code, OpenCode

⚠️ Partial

Python/uv + Node + rustup + Go installed. Claude Code installed + OAuth authenticated. OpenCode installed + stowed. domus-* repos cloned. Multi-remote NOT configured. domus-digitalis setup blocked — missing ~/.secrets/environments/lab/applications.env.age (age-encrypted env never created).

10: AI Stack

Ollama, models, custom modelfiles, API service

❌ Not started

11: Verification

System, desktop, development checklists + btrfs snapshot

❌ Not started

12: Security Hardening

AppArmor MAC, UFW firewall, SSH lockdown, open ports audit

🟡 In progress

AppArmor Phase 1 verified post-reboot (162 profiles, 79 enforce). Phase 2 complete: browsers (Firefox, Chrome, Chromium) confined with credential store deny rules enforced + attach_disconnected for bwrap sandbox. UFW and SSH hardening not started. INC-2026-04-04-002. CR: AppArmor Deployment.

13: Maintenance

Borg automation, TLP battery, cert renewal, systemd timers

❌ Not started

SEC-001

No Mandatory Access Control

⚠️ Phase 2 complete — browsers confined

AppArmor active. Browsers enforced with credential denies. Node/Python profiles pending (Phase 3). CR: AppArmor Deployment.

Pre-Deployment Assessment

What’s Git Versioned (Safe)

Everything in ~/atelier/ is git-managed across 40+ repos. Clone and stow — done.

Category Source Recovery Method

Dotfiles (35 stow packages)

dots-quantum repo

git clone + stow -t ~

Documentation (15 Antora spokes)

domus-* repos (GitHub, GitLab, Gitea)

git clone all remotes

Projects (netapi, Kora, ollama-local)

_projects/personal/ repos

git clone

Neovim config

domus-nvim repo

git clone + stow

SSH config (encrypted)

dots-quantum/ssh/ (age-encrypted)

age -d + stow

Claude Code config

dots-quantum/claude/

stow

Aider config

dots-quantum/aider/

stow

gopass store

v3/ (GPG-encrypted, multi-remote)

gopass clone

GPG keys

YubiKey + backup

gpg --card-status

What’s in Borg (Large Files)

Category Content Recovery

Borg → Synology

Home directory snapshot, non-git data

borg extract from NAS

Seagate Backup

Secondary backup, media, archives

Mount + rsync

Borg backup script (borg-backup-synology.sh) was written for dotfiles-optimus. Must verify it works with dots-quantum paths before relying on it.

What Needs Manual Setup

Item Notes

BIOS/UEFI settings

Secure Boot, TPM, NVIDIA dGPU mode

LUKS passphrase

New encryption key for P16g (don’t reuse Razer’s)

WiFi credentials

Re-enter or restore from gopass

Bluetooth pairing

Kinesis Advantage 360 Pro, Galaxy Buds3 Pro — new pairings needed

Browser state

Firefox profiles not git-versioned — Borg or manual

Ollama models

Re-pull from registry (18GB qwen3-coder, 19GB qwen2.5-coder, etc.)

Borg Backup Validation (CRITICAL — Do Before Deployment)

The backup script borg-backup-synology.sh was written for dotfiles-optimus. It may reference old paths.

Validation Steps

  1. Read the script — check for hardcoded paths:

    cat ~/.local/bin/borg-backup-synology.sh
  2. Check for optimus references:

    grep -i "optimus\|dotfiles-optimus" ~/.local/bin/borg-backup-synology.sh
  3. Verify Borg repo is accessible:

    borg info ssh://evanusmodestus@nas-01/volume1/borg-backups/modestus-razer
  4. List recent archives:

    borg list ssh://evanusmodestus@nas-01/volume1/borg-backups/modestus-razer --last 5
  5. Dry-run a backup:

    borg create --dry-run --stats ssh://evanusmodestus@nas-01/volume1/borg-backups/modestus-razer::test-$(date +%Y%m%d) ~/
  6. Run actual backup if dry-run passes:

    borg-backup-synology.sh
  7. Verify the new archive:

    borg list ssh://evanusmodestus@nas-01/volume1/borg-backups/modestus-razer --last 1
    borg info ssh://evanusmodestus@nas-01/volume1/borg-backups/modestus-razer::$(borg list --last 1 --format '{name}' ssh://evanusmodestus@nas-01/volume1/borg-backups/modestus-razer)

If Script Is Broken

  1. Fix paths in dots-quantum/bin/.local/bin/borg-backup-synology.sh

  2. Commit to dots-quantum

  3. Re-stow: cd ~/atelier/_projects/personal/dots-quantum && stow -t ~ bin

  4. Re-run backup

Metadata

Field Value

PRJ ID

PRJ-2026-04-p16g-deploy

Author

Evan Rosado

Created

2026-04-01

Last Updated

2026-04-03

Status

Operational — completing remaining phases

Deployed

2026-04-02

Hostname

modestus-p16g

VLAN

DOMUS-Secure (10.50.10.x) via WiFi EAP-TLS