Skip to content

About

Reproducible, security-conscious developer workstation for CachyOS + GNOME — documented setup phases and scripts covering shell, AI coding agents, containers, databases, and networking.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

10 Commits

Folders and files

Repository files navigation

CachyOS logo

CachyOS Developer Workstation

A reproducible, security-conscious developer workstation for CachyOS + GNOME.

Modern web development, AI coding agents, containers, databases, remote access, media tools and everyday productivity — documented, scripted and verifiable.


CachyOS GNOME Wayland Catppuccin

zsh Ghostty Node.js Bun Python PostgreSQL Podman Neovim

Tailscale Caddy UFW sops License Maintained

Verified against GNOME Shell 50.5 on Wayland · last audit 2026-10-02


What this repository does

This repository documents and automates a professional CachyOS developer workstation from a clean installation to a complete daily-driver environment.

It is designed around:

  • CachyOS / Arch Linux
  • GNOME + Catppuccin Mocha (Colloid GTK3/GTK4, Tela-circle icons, Bibata cursor)
  • GNOME Shell extensions (dash-to-dock, blur-my-shell, Vitals, user-theme, gsconnect, tilingshell, just-perfection)
  • Ghostty (+ Ptyxis, Alacritty)
  • zsh + oh-my-zsh + Powerlevel10k (CachyOS system packaging), fish retained as fallback
  • Git + GitHub
  • Node.js, npm, pnpm, Bun
  • Python + pipx
  • PostgreSQL + sqlite3
  • Podman
  • Playwright
  • Postman
  • Zed (VS Code optional)
  • Firefox + Chrome + Zen + Brave
  • Claude Code, Codex, Kiro CLI, Pi, OpenCode, Herdr, Hermes
  • Oh My Pi / Oh My Claude / Oh My Codex (oh-my-claude-sisyphus via npm)
  • Tailscale
  • Caddy
  • Proton VPN
  • Kooha (+ OBS Studio optional) + KTorrent
  • Obsidian
  • Thunderbird
  • Telegram Desktop (telegram-desktop package; binary name differs — verify with pacman -Ql)
  • SSHFS
  • Modern CLIs: bat, eza, btop, fastfetch, duf, ripgrep, fd, fzf, delta, lazygit, zoxide, go-yq
  • Terminal workflow: neovim, tmux, mosh (for Tailscale SSH sessions)
  • Runtime management: mise (Node/Python versions), uv (Python projects)
  • Encrypted secrets: age + sops
  • UFW and additional system hardening

The goal is repeatability without blindly copying a personal machine configuration.


Important

This repository is a setup guide and automation starting point, not a universal one-click installer.

Review each phase before executing it on another machine.

Do not commit:

  • SSH private keys
  • API keys
  • cloud credentials
  • .env files containing secrets
  • Tailscale auth keys
  • GitHub tokens
  • AI provider credentials
  • browser profiles
  • personal databases
  • personal shell history

1. Target architecture

                           Internet
                              │
                 ┌────────────┴────────────┐
                 │                         │
             Proton VPN                Tailscale
                 │                         │
                 │                 Private remote access
                 │                         │
          Normal outbound             SSH / services
                 │                         │
                 └────────────┬────────────┘
                              │
                    ┌─────────▼─────────┐
                    │  CachyOS + GNOME  │
                    └─────────┬─────────┘
                              │
       ┌──────────────────────┼──────────────────────┐
       │                      │                      │
   Development              AI                  Infrastructure
       │                      │                      │
 Node / Bun / pnpm       Claude / Codex        PostgreSQL
 Python / Playwright     Kiro / Pi             Podman
 VS Code / Zed           OpenCode / Herdr      Caddy
       │                      │                      │
       └──────────────────────┼──────────────────────┘
                              │
                       Daily productivity
                              │
          Obsidian / Thunderbird / Telegram
             OBS / Kooha / KTorrent

2. Repository structure

cachyos-dev-workstation/
├── README.md
├── CLAUDE.md
├── LICENSE
├── .gitignore
├── docs/
│   ├── 00-overview.md
│   ├── 01-installation.md
│   ├── 02-base-system.md
│   ├── 03-gnome.md
│   ├── 04-development.md
│   ├── 05-ai-tooling.md
│   ├── 06-browsers-editors.md
│   ├── 07-databases-containers.md
│   ├── 08-networking.md
│   ├── 09-security.md
│   ├── 10-productivity-media.md
│   ├── 11-verification.md
│   ├── 12-maintenance.md
│   ├── 13-terminals.md
│   ├── 14-shell.md
│   └── 15-cli-tooling.md
├── scripts/
│   ├── 00-system-update.sh
│   ├── 01-base-packages.sh
│   ├── 02-development.sh
│   ├── 03-ai-tools.sh
│   ├── 04-applications.sh
│   ├── 05-security-audit.sh
│   ├── 06-cli-tooling.sh
│   ├── 07-gnome-theming.sh
│   └── verify.sh
├── assets/
│   └── cachyos.svg
└── .github/
    └── workflows/
        └── markdown.yml

The scripts are intentionally separated. You can execute the documentation manually or use the scripts as a starting point.

Documentation index

Document Covers
🗺️ 00-overview Scope and design goals
💽 01-installation Clean CachyOS install
🧱 02-base-system Base packages, build tools
🎨 03-gnome GNOME, Catppuccin theming, extensions
🛠️ 04-development Languages and runtimes
🤖 05-ai-tooling AI coding agents and MCP
🌐 06-browsers-editors Browsers, Zed, VS Code
🗄️ 07-databases-containers PostgreSQL, Podman
🔗 08-networking Tailscale, Caddy, SSHFS
🔐 09-security UFW, SSH hardening, age/sops
📦 10-productivity-media Obsidian, OBS, Kooha
✅ 11-verification Drift detection
🔄 12-maintenance Updates and upkeep
🖥️ 13-terminals Ghostty, Ptyxis, Alacritty
🐚 14-shell zsh + oh-my-zsh, the PATH trap
⚡ 15-cli-tooling Modern CLI replacements

3. Quick start

Fresh CachyOS installation

Install CachyOS using the official installer and select:

  • GNOME
  • UEFI
  • your intended filesystem
  • your intended bootloader
  • your normal user account

Then reboot into the installed system.

CachyOS provides multiple desktop environments through its current installer, including GNOME.

Clone this repository

git clone https://github.com/RavenRepo/cachyos-dev-workstation.git
cd cachyos-dev-workstation

Run the phases

bash scripts/00-system-update.sh
bash scripts/01-base-packages.sh
bash scripts/02-development.sh
bash scripts/03-ai-tools.sh
bash scripts/04-applications.sh
bash scripts/05-security-audit.sh
bash scripts/06-cli-tooling.sh
bash scripts/07-gnome-theming.sh
bash scripts/verify.sh

Do not run all phases blindly on an existing machine. Read the corresponding documentation first.


4. Phase map

Phase Purpose
00 System update and baseline
01 Git, build tools, shell (zsh stack + fish fallback) and common utilities
02 Node, Bun, pnpm, Python, PostgreSQL, Podman, Playwright
03 AI coding agents and agent runtimes
04 Browsers, editors, terminals, themes, VPN, productivity and media
05 Security audit helpers
06 Terminal editor, multiplexer, git tooling, runtime managers, secrets tooling
07 GNOME theming (Catppuccin Mocha, GTK3 + GTK4, icons, panel) — no root
Verify Validate the installation

5. Base system

Update first:

sudo pacman -Syu

Install core tooling:

sudo pacman -S --needed \
  base-devel \
  git \
  curl \
  wget \
  unzip \
  zip \
  jq \
  ripgrep \
  fd \
  fzf \
  tree \
  rsync \
  openssh \
  man-db \
  man-pages \
  bat \
  eza \
  btop \
  fastfetch \
  duf \
  sqlite3

Install the AUR helper used by this setup:

sudo pacman -S --needed yay

Verify:

git --version
yay --version
curl --version
rg --version
bat --version
eza --version
sqlite3 --version

6. Shell

This workstation uses zsh with oh-my-zsh and Powerlevel10k as the primary interactive shell. fish is retained as a fallback.

Full detail, including the migration procedure and the PATH trap described below, is in docs/14-shell.md.

sudo pacman -S --needed \
  zsh oh-my-zsh-git cachyos-zsh-config zsh-theme-powerlevel10k \
  zsh-autosuggestions zsh-completions zsh-syntax-highlighting \
  zsh-history-substring-search

All of these are in official CachyOS/extra repositories. The AUR is not needed.

How this differs from a normal oh-my-zsh install

CachyOS packages oh-my-zsh system-wide at /usr/share/oh-my-zsh, not ~/.oh-my-zsh, and pacman owns updates.

source /usr/share/cachyos-zsh-config/cachyos-config.zsh

That single line provides the Powerlevel10k instant prompt, ZSH=/usr/share/oh-my-zsh, plugins=(git fzf extract), oh-my-zsh itself, and the p10k theme. Do not clone oh-my-zsh into $HOME on top of it, and do not run upgrade_oh_my_zsh. Custom plugins belong in $ZSH_CUSTOM.

Before changing your login shell

A clean zsh login does not inherit ~/.local/bin or ~/.bun/bin. fish gets them from fish_add_path in cachyos-config.fish; the CachyOS zsh config has no equivalent. Since the AI agent CLIs live in ~/.local/bin and bun/omp live in ~/.bun/bin, running chsh without fixing PATH first removes the entire agent toolchain from your shell.

This is invisible when testing from an existing session, because a child shell inherits the parent's PATH. Test with a scrubbed environment instead:

env -i HOME="$HOME" USER="$USER" TERM=xterm /usr/bin/zsh -ic 'print -l $path'

Add the PATH block from docs/14-shell.md to ~/.zshrc above the source line, then:

exec zsh -l
p10k configure
bash scripts/verify.sh
chsh -s /usr/bin/zsh     # only after the above passes

Log out and back in.

fish (fallback)

sudo pacman -S --needed fish cachyos-fish-config
source /usr/share/cachyos-fish-config/cachyos-config.fish

# disables the greeting and its fastfetch block
function fish_greeting
end

Reverting is chsh -s /usr/bin/fish. Keep ~/.config/fish/config.fish in place so the fallback stays usable.

Note that fish is not POSIX-compatible, so the export VAR=... lines that upstream curl | bash installers append to ~/.zshrc and ~/.bashrc have no effect in fish and must be rewritten by hand. That is the main practical reason this workstation prefers zsh.


7. GNOME

Install GNOME components as needed:

sudo pacman -S --needed \
  gnome-shell \
  gnome-control-center \
  gnome-tweaks \
  gnome-keyring \
  gnome-terminal \
  nautilus \
  file-roller \
  xdg-user-dirs

For GNOME extensions:

sudo pacman -S --needed gnome-extensions-app

Verify:

gnome-shell --version
gnome-extensions version

Themes, extensions, terminals

This workstation uses Catppuccin Mocha: Colloid-Purple-Dark-Catppuccin for GTK3 and GTK4/libadwaita, Tela-circle-purple-dark icons, Bibata-Modern-Ice cursor, Adwaita Sans 11, purple accent, stock shell theme with a rounded blurred panel.

bash scripts/07-gnome-theming.sh    # no root required

Two things that trip up most GNOME theming guides:

  • Nothing in GNOME Tweaks themes GTK4/libadwaita apps. "Legacy Applications" sets the GTK3 theme only. GTK4 is themed exclusively by ~/.config/gtk-4.0/gtk.css, which is why the theme is built from source with vinceliuice's -l flag rather than installed from the AUR.
  • Open Bar does not support GNOME 50. Panel styling here goes through Blur My Shell's corner-radius key instead. Always check an extension against the extensions.gnome.org API before installing.

adw-gtk3-dark is the documented fallback if the custom theme becomes a maintenance burden — it matches both toolkits, honours the native accent colour, and survives GNOME upgrades untouched.

Full detail, verified findings and rollback snapshots: docs/03-gnome.md. The reproducible extension list (dash-to-dock, blur-my-shell, Vitals, user-theme, gsconnect, CoverflowAltTab, tilingshell, just-perfection) is in the same document.

Ghostty is the primary terminal (Ptyxis and Alacritty as alternatives); see docs/13-terminals.md. GNOME Terminal is intentionally not installed.

Recommended philosophy:

  • keep the desktop minimal
  • install extensions deliberately
  • avoid extensions that duplicate core GNOME functionality
  • remove abandoned extensions
  • review extension compatibility after GNOME upgrades
  • snapshot dconf dump /org/gnome/ before any theming change

8. Git and GitHub

Configure Git identity:

git config --global user.name "YOUR NAME"
git config --global user.email "YOUR_EMAIL"

Recommended defaults:

git config --global init.defaultBranch main
git config --global pull.rebase false
git config --global fetch.prune true
git config --global core.editor "code --wait"

Verify:

git config --global --list

SSH authentication

Generate an Ed25519 key:

ssh-keygen -t ed25519 -C "YOUR_EMAIL"

Start the agent:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Print the public key:

cat ~/.ssh/id_ed25519.pub

Add it to GitHub.

Test:

ssh -T git@github.com

Never publish ~/.ssh/id_ed25519.


9. Node.js

Install Node.js and npm from the system repositories:

sudo pacman -S --needed nodejs npm

Verify:

node --version
npm --version

For projects that require multiple Node versions, use a version manager rather than replacing system packages manually.


10. pnpm

Install:

sudo pacman -S --needed pnpm

Verify:

pnpm --version

corepack is a separate extra package — it is not bundled with nodejs or npm on Arch, and it is not installed by this setup. Standalone pnpm needs no corepack enable step. Install the corepack package explicitly only if a project requires it.


11. Bun

Install Bun using its upstream installer:

curl -fsSL https://bun.sh/install | bash

Reload your shell or source the generated environment.

Verify:

bun --version

12. Python

Install the system Python stack:

sudo pacman -S --needed \
  python \
  python-pip \
  python-pipx

Initialize pipx:

pipx ensurepath

Verify:

python --version
pip --version
pipx --version

Use virtual environments for project dependencies.


13. PostgreSQL

Install:

sudo pacman -S --needed postgresql

Initialize the database cluster:

sudo -u postgres initdb -D /var/lib/postgres/data

Enable and start:

sudo systemctl enable --now postgresql

Verify:

systemctl status postgresql --no-pager

Open PostgreSQL:

sudo -u postgres psql

Create a development role/database according to the project instead of exposing PostgreSQL to the network by default.

Check listening sockets:

sudo ss -lntp | grep postgres

Prefer local-only PostgreSQL for development.


14. Podman

Install:

sudo pacman -S --needed \
  podman \
  podman-compose \
  buildah \
  skopeo

Verify:

podman --version
podman info

Rootless containers are preferred.

Test:

podman run --rm docker.io/library/hello-world

Check:

podman ps
podman images

Do not globally expose container ports through the firewall. Audit each published port first.


15. Playwright

For Node projects:

pnpm add -D playwright

Install browsers:

pnpm exec playwright install

For a system-wide development environment, keep Playwright browser installation project-specific whenever possible.

Verify:

pnpm exec playwright --version

16. Editors

VS Code

Choose one installation source.

Repository package:

sudo pacman -S --needed code

Or AUR binary package:

yay -S visual-studio-code-bin

Do not install both unless you intentionally need both variants.

Verify:

code --version

Zed

sudo pacman -S --needed zed

Verify:

zeditor --version

API clients

yay -S --needed postman-bin

Verify with the real binary name:

command -v postman

17. Browsers

Install the browsers you actually use.

yay -S --needed \
  google-chrome \
  zen-browser-bin \
  brave-bin

Verify:

Firefox ships with CachyOS GNOME. Verify with the real binary names:

google-chrome-stable --version
zen-browser --version
brave --version
firefox --version

Keep browser profiles separate from the configuration repository.


18. AI development tools

AI tools change quickly. Prefer their official installers and verify versions after installation.

Claude Code

Current upstream installation:

curl -fsSL https://claude.ai/install.sh | bash

Verify:

claude --version

Authenticate:

claude

Do not use sudo npm install -g @anthropic-ai/claude-code.

Kiro CLI

Current upstream installer:

curl -fsSL https://cli.kiro.dev/install | bash

Verify:

kiro-cli --version

If the command name differs in a future release, follow the current Kiro CLI documentation.

Codex

Install using the current official OpenAI instructions for your account/platform.

Keep authentication outside this repository.

OpenCode

Prefer the current upstream installer:

curl -fsSL https://opencode.ai/install | bash

Alternatively, if the Arch package is current on your system:

sudo pacman -S --needed opencode

Verify:

opencode --version

Herdr

Herdr is an AI-agent runtime, not Laravel Herd.

Install:

curl -fsSL https://herdr.dev/install.sh | sh

Verify:

herdr --version

Install integrations as needed:

herdr integration install pi
herdr integration install omp
herdr integration install claude
herdr integration install codex
herdr integration install opencode
herdr integration install hermes

Only install integrations you actually use.

Observed on this workstation (2026-10-02): claude 2.1.287, codex 0.159.3, kiro-cli 2.21.2, pi 0.87.1, herdr 0.9.3 (all ~/.local/bin via upstream installers), opencode v2.0.11 (~/.opencode/bin via upstream installer), omp 18.4.4 (~/.bun/bin/omp via Bun), plus hermes/hermes-acp/hermes-agent v0.21.1, antigravity (IDE v2.13.0, ~/.local/bin), agent-memory, jev-gate. npm global: oh-my-claude-sisyphus, neon, llm-checker. Bun global: @oh-my-pi/pi-coding-agent. Agent state (~/.claude/, ~/.codex/config.toml) stays out of Git. Details: docs/05-ai-tooling.md.


19. Agent ecosystem

This setup can include:

Claude Code
Codex
Kiro CLI
Pi
OpenCode
Herdr
Oh My Pi
Oh My Claude
Oh My Codex
Hermes

Treat each tool as an independent executable.

Do not put:

  • provider tokens
  • MCP credentials
  • agent secrets
  • personal prompts containing secrets
  • private project data

into this repository.


20. MCP servers

Recommended MCP categories:

Codebase MCP
Context7
Sequential Thinking
Exa
Browserbase

Install and configure them at the appropriate agent/client layer.

Do not copy credentials into Git.

A safe repository pattern is:

docs/
  ai-tooling.md

examples/
  mcp.example.json

.local/
  # ignored

Use placeholders in example configuration.


21. Tailscale

Install using the official package/instructions appropriate for your system.

sudo pacman -S --needed tailscale

Enable:

sudo systemctl enable --now tailscaled

Authenticate:

sudo tailscale up

Check:

tailscale status
tailscale ip
tailscale netcheck

Tailscale should be the preferred path for private remote access.

Avoid exposing SSH globally to the public internet.


22. Tailscale SSH

If you intentionally use Tailscale SSH:

sudo tailscale set --ssh

Then verify:

tailscale debug prefs
tailscale status

Tailscale SSH still depends on your tailnet access policy.

Do not assume that knowing a Tailscale IP automatically grants SSH access.


23. OpenSSH hardening

Install:

sudo pacman -S --needed openssh

Create a drop-in:

sudo nano /etc/ssh/sshd_config.d/10-hardening.conf

Suggested baseline:

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
LoginGraceTime 20
ClientAliveInterval 300
ClientAliveCountMax 2

Before restarting SSH, validate the configuration:

sudo sshd -t

Then:

sudo systemctl restart sshd

If your workflow uses Tailscale SSH exclusively, do not expose TCP/22 globally through UFW.


24. UFW

Check current status:

sudo ufw status verbose

Set the baseline:

sudo ufw default deny incoming
sudo ufw default allow outgoing

Enable:

sudo ufw enable

Do not blindly run:

sudo ufw allow 22/tcp

For this workstation, SSH should preferably remain private through Tailscale.

Inspect:

sudo ufw status numbered

Remove an accidental global SSH rule:

sudo ufw delete allow 22/tcp

25. Firewall audit

Before opening any port:

sudo ss -lntup

Also inspect:

sudo ss -lntp
sudo ss -lnup

Categorize every listener:

127.0.0.1 / ::1
    Local-only service.

Tailscale IP
    Private tailnet service.

0.0.0.0 / ::
    Potentially network-accessible service.

Never open a port simply because an application says it can use one.


26. Caddy

Caddy is intended for controlled reverse proxying and local/Tailscale service exposure.

Install:

sudo pacman -S --needed caddy

Verify the binary before starting anything:

caddy version

Read the packaged configuration before enabling the unit, because enabling it starts a listener you have not reviewed:

cat /etc/caddy/Caddyfile
caddy validate --config /etc/caddy/Caddyfile

Once your own configuration is in place:

sudo systemctl enable --now caddy
systemctl status caddy --no-pager
sudo ss -lntp | grep caddy

Confirm the bind address in that last command. 127.0.0.1 or a Tailscale address is what you want for development; 0.0.0.0 means the machine is serving the network.

Start with local services.

Example conceptual configuration:

service.example.internal {
    reverse_proxy 127.0.0.1:3000
}

Do not publish a development application to the public internet until:

  1. authentication exists
  2. firewall rules are reviewed
  3. Caddy configuration is validated
  4. logs are monitored
  5. secrets are protected

27. SSHFS

Install:

sudo pacman -S --needed sshfs

Prefer Tailscale addresses for remote machines.

Example:

mkdir -p ~/mnt/remote
sshfs user@tailscale-host:/path ~/mnt/remote

For permanent mounts, use a systemd user mount rather than an ad-hoc shell command.

Unmount:

fusermount3 -u ~/mnt/remote

28. Proton VPN

Current Arch installation:

sudo pacman -S --needed proton-vpn-gtk-app gnome-keyring

Proton VPN's Linux documentation also calls out NetworkManager and systemd-resolved requirements for relevant functionality.

Launch:

protonvpn-app

Do not enable a VPN kill switch until you have tested interaction with:

  • Tailscale
  • UFW
  • local development
  • DNS
  • Podman
  • Caddy

A kill switch can intentionally break remote-access and development workflows if routing is not designed first.


29. Productivity and communication

Install:

sudo pacman -S --needed \
  obsidian \
  thunderbird \
  telegram-desktop

Launch:

obsidian
thunderbird
telegram-desktop

Keep application profiles outside this repository.


30. Recording and media

OBS Studio

Install:

sudo pacman -S --needed obs-studio

Verify:

obs --version

Recommended architecture:

Webcam
   │
   └── Rounded webcam overlay
             │
Screen ──────┼──► OBS
             │
Mic ─────────┘

For the described workflow:

  • use the boAt earbuds microphone as the primary microphone
  • avoid relying on desktop audio as the primary recording source
  • configure PipeWire routing in OBS
  • use mic filters
  • keep desktop audio optional

Kooha

sudo pacman -S --needed kooha

Launch:

kooha

Kooha is useful for quick screen recordings; OBS remains the full production workflow.


31. KTorrent

Install:

sudo pacman -S --needed ktorrent

Launch:

ktorrent

Do not automatically open a torrent listening port through UFW.

First inspect:

sudo ss -lntup

Then decide whether inbound peer connectivity is actually needed.


32. Security baseline

Update regularly

sudo pacman -Syu

Review failed services

systemctl --failed

Review enabled services

systemctl list-unit-files --state=enabled

Review listening sockets

sudo ss -lntup

Review firewall

sudo ufw status verbose

Review Tailscale

tailscale status
tailscale netcheck

Review disk permissions

ls -ld ~
ls -ld ~/.ssh

SSH directory should normally be:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/* 2>/dev/null || true
chmod 644 ~/.ssh/*.pub 2>/dev/null || true

33. No AppArmor policy

This setup does not require AppArmor.

Security layers are instead built around:

  • timely updates
  • least privilege
  • rootless containers
  • UFW
  • Tailscale private networking
  • SSH key authentication
  • systemd service management
  • controlled reverse proxying
  • careful port exposure
  • secrets outside Git
  • GitHub repository security
  • application-level authentication

If you later add another mandatory access-control framework, document it as a separate architectural decision.


34. Secrets management

Never commit:

.env
.env.*
*.pem
*.key
id_rsa
id_ed25519
credentials.json
service-account.json
tokens.json

Use:

  • environment variables loaded from a 600-mode file outside Git
  • age + sops for secrets that must be versioned
  • GNOME Keyring
  • application credential stores
  • password managers
  • secret managers

The machine-local pattern this workstation uses:

mkdir -p ~/.config/secrets && chmod 700 ~/.config/secrets
install -m 600 /dev/null ~/.config/secrets/env
# put `export SOME_API_KEY="..."` in that file, then in ~/.zshrc:
[[ -r "$HOME/.config/secrets/env" ]] && source "$HOME/.config/secrets/env"

Do not assign credentials inline in .bashrc, .zshrc, or .config/fish/config.fish. Those files are mode 644 by default, they end up in dotfiles repositories, and the value leaks into ~/.bash_history as well. scripts/verify.sh fails the build if it finds an inline export *KEY=, *TOKEN=, or *SECRET= in a shell rc file.

Anything that has ever been in a shell rc file, a history file, or a Git object must be rotated, not merely deleted. Full procedure in docs/09-security.md.


35. Development project conventions

Recommended workspace:

~/Projects/            # active work (observed 2026-09-19: anatomy, ladder, stuntkit, ...)
├── personal/
├── work/
├── experiments/
├── open-source/
└── archived/
/mnt/kronos/Projects/  # bulk archive (129 entries observed 2026-09-19)
/mnt/kronos/jev/        # Jev risk gate (canonical, not a project workspace)

Example:

mkdir -p ~/Projects/{personal,work,experiments,open-source,archived}

Keep ~/ root clean: ~/main, ~/src/theming, ~/postiz, ~/twenty, ~/researchdoc, stray ~/package.json / ~/node_modules belong under ~/Projects/ or /mnt/kronos/Projects/.

A typical project:

project/
├── .github/
├── docs/
├── src/
├── tests/
├── scripts/
├── public/
├── .env.example
├── .gitignore
├── README.md
├── package.json
└── pnpm-lock.yaml

36. Verification

Run:

bash scripts/verify.sh

Manual verification:

echo "=== OS ==="
cat /etc/os-release

echo
echo "=== Kernel ==="
uname -r

echo
echo "=== Git ==="
git --version

echo
echo "=== Node ==="
node --version

echo
echo "=== pnpm ==="
pnpm --version

echo
echo "=== Bun ==="
bun --version

echo
echo "=== Python ==="
python --version

echo
echo "=== PostgreSQL ==="
psql --version

echo
echo "=== Podman ==="
podman --version

echo
echo "=== Tailscale ==="
tailscale version

echo
echo "=== Firewall ==="
sudo ufw status verbose

echo
echo "=== Listening sockets ==="
sudo ss -lntup

37. Maintenance

Monthly:

sudo pacman -Syu

Review AUR packages:

yay

Review services:

systemctl --failed

Review network exposure:

sudo ss -lntup
sudo ufw status numbered

Review Tailscale devices:

tailscale status

Review containers:

podman ps -a
podman images

Review PostgreSQL:

systemctl status postgresql --no-pager

Review Caddy:

systemctl status caddy --no-pager

38. Troubleshooting philosophy

When something breaks, inspect the system before changing configuration.

Use:

systemctl status SERVICE --no-pager
journalctl -u SERVICE -b --no-pager
ss -lntup
ip addr
ip route
resolvectl status

For user services:

systemctl --user status SERVICE --no-pager
journalctl --user -u SERVICE -b --no-pager

For PipeWire:

wpctl status

For Tailscale:

tailscale status
tailscale netcheck
tailscale debug prefs

For firewall:

sudo ufw status verbose

Avoid random fixes from old blog posts.


39. What should NOT be automated

The following should remain deliberate:

  • bootloader replacement
  • disk partitioning
  • filesystem formatting
  • SSH key creation
  • GitHub authentication
  • Tailscale authentication
  • VPN kill-switch activation
  • firewall port opening
  • public reverse proxy exposure
  • database network exposure
  • AI credentials
  • browser profile migration
  • secret manager configuration

40. Roadmap

  • Baseline GNOME configuration (Catppuccin Mocha: Colloid GTK3+GTK4 / Tela-circle / Bibata, docs/03-gnome.md)
  • GTK4/libadwaita theming solved via ~/.config/gtk-4.0/gtk.css (docs/03-gnome.md)
  • Root-free, idempotent theming phase (scripts/07-gnome-theming.sh)
  • Reproducible GNOME extension list (docs/03-gnome.md)
  • zsh + oh-my-zsh migration with the PATH trap documented (docs/14-shell.md)
  • CLI tooling phase with verified package names (docs/15-cli-tooling.md)
  • Machine-local secrets pattern + age/sops workflow (docs/09-security.md)
  • verify.sh rewritten to detect repo/system drift instead of masking it
  • Add Caddy templates
  • Add rootless Podman Quadlet examples
  • Add systemd user SSHFS examples
  • Add hardened sysctl profile
  • Add security audit script
  • Add workstation backup strategy (restic repository + systemd timer)
  • Add dotfiles repository integration (stow layout)
  • Decide on shared shell history (atuin) across zsh and fish
  • Pick a password-manager CLI and wire sops to it
  • Add optional NVIDIA/Wayland tuning
  • Replace the local sassc extraction with pacman -S sassc libsass
  • Decide on floating panel (--tweaks float) vs current rounded panel
  • Install refine for GNOME settings not exposed in Settings/Tweaks
  • Add developer project bootstrap scripts
  • Add CI for Markdown/link validation

41. References

Official documentation should take precedence over this repository when software changes.


42. License

MIT. See LICENSE.

43. Contributing and community


Maintainer

Amit Kumar

GitHub

Issues and pull requests welcome. Please do not include machine-specific credentials, hostnames or Tailscale keys in reports.


Built on CachyOS · themed with Catppuccin · themes by vinceliuice

About

Reproducible, security-conscious developer workstation for CachyOS + GNOME — documented setup phases and scripts covering shell, AI coding agents, containers, databases, and networking.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages