Lab date: Sunday, September 20, 2026
Part 1: Post-update health check (Omarchy, HP laptop)
After updating my Omarchy laptop to kernel 7.2.3-arch1-3, I ran a structured health check:
| Command | What it told me |
|---|---|
uname -r / pacman -Q linux | The running kernel matched the installed package, so the update took. |
systemctl --failed | 0 failed services. |
journalctl -p 3 -xb | Error-level messages from this boot (-p 3 = errors, -b = this boot, -x = explanations). |
Most of the journal turned out to be harmless noise: SGX/TDX (CPU features my hardware doesn’t offer), lis3lv02d (HP’s drop sensor), ACPI BIOS Error ... WMID (HP firmware bugs), and wpa_supplicant notices. One line mattered: MSFT0101 ... failed to claim resource ... -16. My TPM chip couldn’t start because of a firmware resource conflict.
Part 2: The 90-second boot delay
The investigation:
systemd-analyzeshowed userspace taking 1min 38s.systemd-analyze blameshowed nothing slow. That puzzled me until I learned that a wait isn’t a service, so it never shows up there.systemd-analyze critical-chainfound the culprit:tpm2.target→sysinit.target→ everything else. Systemd was waiting 90 seconds for a TPM device that never appeared, and nearly every service on my system was waiting with it.
[SCREENSHOT: systemd-analyze before — 2min 1.986s total]
[SCREENSHOT: critical-chain output showing tpm2.target]
Safety checks before changing anything:
My disk is LUKS-encrypted, so before touching the TPM I needed to be sure my disk unlock didn’t depend on it.
cat /proc/cmdlineshowedcryptdevice=, which means Arch’s classicencrypthook: passphrase-only unlock, no TPM involved.sudo cat /etc/crypttabcontained only comments, so no other volumes depended on the TPM either.
The fix:
sudo cp /etc/default/limine /etc/default/limine.bak— I made a backup first.- I appended
KERNEL_CMDLINE[default]+=" systemd.tpm2_wait=0"to the file withtee -a. sudo limine-updaterebuilt the boot images for both of my kernels (stocklinuxandlinux-omarchy).grepconfirmed the parameter was in/boot/limine.confbefore I rebooted.
The lesson from a stale result: my first check after the fix showed identical numbers, down to the millisecond. uptime and journalctl --list-boots proved I hadn’t actually rebooted yet. After a real reboot, userspace went from 1min 38s to 5.3s, with no TPM timeouts.
[SCREENSHOT: systemd-analyze after — 5.290s userspace]
The lesson about which clock I was reading: the “kernel” time then showed 2min 58s, which briefly worried me. journalctl -o short-monotonic misled me, because it shows when journald received each message, and journald doesn’t run inside my initramfs. sudo dmesg showed the kernel’s own timestamps: device-mapper ready at 2.7s, root mounted at 178s. That gap was my LUKS passphrase screen sitting there waiting for me, not a system problem. The machine itself boots in about 18 seconds plus however long I take to type my passphrase.
[SCREENSHOT: dmesg lines showing the 2.7s → 178s passphrase gap]
Part 3: Setting up Claude Code on Omarchy
- Installation: running
claude --versiontriggered mise (Omarchy’s tool manager) to install Claude Code 2.1.278 on the spot, because my~/.config/mise/config.tomlalready listed it. - Login: Sonnet 5 · Claude Pro.
- Permission mode: I set it to Manual through
/configand confirmed it saved after a restart (⏸ manual mode on). - Output style: Learning. I caught that typing
Learningwithout the/only produced Claude saying the style had changed, while/output-styleitself still showeddefault (current). The real command,/output-style Learning, gave output marked with⎿, which is how Claude Code shows actual tool output, and/output-stylethen confirmed Learning (current). - Standing instructions: I created
~/.claude/CLAUDE.mdtelling Claude Code to explain every command, flag, and system change before running anything. I used acat >> ... << 'EOF'heredoc to write it, and/memoryconfirmed it loaded as User instructions.
[SCREENSHOT: /output-style showing Learning (current)]
How I read permission prompts now:
- Yes means once. I’m sticking with this while I learn.
- “Don’t ask again for …
*“ — the*is a wildcard that allows anything matching. I avoid those. - “Switch to auto mode” would undo Manual mode. I ignore it.
- “Accept edits” lets file changes go through without asking. I skip it for now.
- The faint text in the input box is only a suggestion. Tab accepts it, and nothing is sent until I press Enter.
[SCREENSHOT: Claude Code’s first permission prompt, with its explanation above it]
Part 4: My Black Hat Python workspace
mkdir -p ~/projects/bhp && cd ~/projects/bhp
python -m venv .venv
source .venv/bin/activate
- I verified the venv with
echo $VIRTUAL_ENVandwhich python, both pointing into.venv. Omarchy’s prompt doesn’t display(.venv), so those two checks are my indicator. - I installed paramiko 5.0.0 (SSH) and scapy 2.7.0 (packets), plus their transitive dependencies (cryptography, bcrypt, PyNaCl, cffi, pycparser, invoke).
requirements.txtrecords the pinned versions. To rebuild the environment anywhere:pip install -r requirements.txt.
Shell concepts I picked up: ; runs the next command no matter what, while && runs it only if the previous command succeeded. > overwrites a file and >> appends to it. ~ means my home folder. $VAR means a variable’s value.
My Neovim escape hatch: Esc, then :q!, then Enter quits without saving.
Other tips I’m keeping: PrtSc takes a screenshot, Super+K lists Omarchy’s shortcuts, Ctrl+L redraws a scrambled Claude Code screen, and Ctrl+O shows the full command output behind “Ran 1 shell command.”
Next up: Chapter 2
How I pick up where I left off:
cd ~/projects/bhp
source .venv/bin/activate
claude --continue
--continue reopens my most recent Claude Code conversation in that folder, so it remembers where I stopped.
Where I am: Chapter 2, the TCP client, starting with import socket. Next comes creating the socket with AF_INET (IPv4) and SOCK_STREAM (TCP), then connect, send, and recv. After the client, the chapter moves on to a TCP server, a UDP client, and eventually a netcat replacement and SSH with paramiko.
Habits I’m keeping:
- Type every line myself, and compare it with the book.
- Verify Claude’s claims with the tool itself, not just its summary.
- Say Yes once, and avoid wildcards.
- Scapy sniffing will need
sudo. I’ll set that up properly when I reach those chapters.
Too many times I’ve copied commands without understanding them. This setup makes me slow down and learn what each one actually does — and that’s the whole point.