aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archive/task-archive.org74
-rwxr-xr-xscripts/cmail-setup-finish.sh44
-rw-r--r--todo.org278
-rw-r--r--working/velox-reinstall/velox-reinstall-runbook.org9
-rw-r--r--working/velox-reinstall/velox-uefi-boot-entry-reference.org75
-rw-r--r--working/velox-touchpad-interrupt/touchpad-module-underside-2026-08-15.jpgbin0 -> 3990419 bytes
6 files changed, 383 insertions, 97 deletions
diff --git a/archive/task-archive.org b/archive/task-archive.org
index 2925180..ba43804 100644
--- a/archive/task-archive.org
+++ b/archive/task-archive.org
@@ -1627,3 +1627,77 @@ Addendum (Craig, 2026-07-07): DO backport the 3.5-entry height convention — ev
** DONE [#B] Absorb the clock-panel project into the dotfiles :feature:waybar:dotfiles:
CLOSED: [2026-07-18 Sat]
Absorbed into =~/.dotfiles= (commit 3fab11d): package =clock/src/clock/= (renamed from clock_panel), the six PNG watchface layers packaged inside the module at =clock/src/clock/assets/=, a stowed =clock-panel= shell shim (LD_PRELOADs gtk4-layer-shell), waybar left-click now =clock-panel toggle= with the absolute path dropped, tests converted pytest→unittest into =tests/clock/= plus an asset-load guard. Kept the layer-shell overlay and the socket toggle. The standalone repo is archived (ARCHIVED.md), kept for its design history. Verified live: the bar click renders the polished watchface.
+** DONE [#A] Velox boot recovery — no kernel in BE :bug:velox:zfs:
+CLOSED: [2026-07-19 Sun]
+Recovered. Velox boots linux-lts 6.18.38 and is back on the tailnet (up 1d+, /boot holds initramfs-linux-lts.img). The pre-pacman ZFS snapshot rollback restored the kernel from the ZBM recovery shell.
+Velox won't boot: ZBM prompts for the passphrase, unlocks, then reports no bootable environment with a kernel. Cause: an interrupted kernel =-Syu= removed the old kernel and never installed the new one — /mnt/be/boot (from zroot/ROOT/default) holds ONLY intel-ucode.img; vmlinuz-linux + both initramfs are gone. /boot lives inside zroot/ROOT/default (no separate boot dataset), so root-dataset snapshots capture it.
+
+Status 2026-07-15: a first rollback attempt did NOT fix it (square zero after reboot) — suspected typo in the snapshot name, so the rollback likely errored and did nothing. NOT verified. Next session: verify state in the ZBM recovery shell BEFORE any reboot.
+
+Recovery lever: the pre-pacman ZFS snapshot hook (live on velox since 2026-06-29) snapshots zroot/ROOT/default@pre-pacman_<ts> before every pacman transaction. The newest =pre-pacman_<ts>= predating the failed upgrade holds the intact old kernel — roll back to it.
+
+Morning steps (Craig at velox ZBM → recovery shell, Ctrl+R):
+#+begin_src sh
+# 1. pool writable + key loaded
+zpool get readonly zroot
+zfs get -H -o value keystatus zroot/ROOT/default
+# if readonly=on: zpool export zroot && zpool import -f -N zroot
+# if keystatus=unavailable: zfs load-key zroot
+
+# 2. list snapshots — COPY THE EXACT NAME (the typo bit here last time)
+zfs list -t snapshot -o name,creation zroot/ROOT/default | grep pre-pacman
+
+# 3. see current /boot state (read-only mount)
+umount /mnt/be 2>/dev/null; mkdir -p /mnt/be
+mount -t zfs -o zfsutil,ro zroot/ROOT/default /mnt/be
+ls -la /mnt/be/boot
+
+# 4. if /boot still shows only intel-ucode.img: redo rollback with the exact name
+umount /mnt/be 2>/dev/null
+zfs rollback -r zroot/ROOT/default@pre-pacman_<EXACT-TS> # -r, NOT -R
+
+# 5. VERIFY before reboot — remount RO, confirm the kernel is back
+mount -t zfs -o zfsutil,ro zroot/ROOT/default /mnt/be
+ls -la /mnt/be/boot # MUST show vmlinuz-linux + initramfs-linux.img
+umount /mnt/be
+
+# 6. only once /boot shows a kernel:
+zpool export zroot && reboot
+#+end_src
+Scope: only zroot/ROOT/default reverts; /home, /var, /media are separate datasets, untouched. After boot: =pacman -Syu= attended, confirm /boot holds vmlinuz-linux + initramfs before any shutdown. Full diagnosis: =inbox/PROCESSED-2026-07-15-0002-from-.emacs.d-velox-boot-failure-handoff.org=; ZBM photo: =inbox/PROCESSED-2026-07-15-0002-from-.emacs.d-PXL_20260715_043758976.jpg= (local on ratio; inbox is gitignored).
+** DONE [#C] Restore date-format scrolling on the waybar date module :feature:waybar:dotfiles:quick:
+CLOSED: [2026-07-19 Sun]
+Shipped dotfiles 9dfe082: date-only ring (ordinal/full/longdate), on-scroll rewired, layout guard flipped. UTC/time stay on the time module.
+Date and time are separate fixed-position controls. The time display cycles its
+own formats, including UTC; the date/calendar control cycles date-only formats
+and never displays a second time. Implement the dedicated format rings,
+tooltip behavior, and tests together in the dotfiles Waybar configuration.
+Reference material for the compact clock/chronograph treatment is filed in
+[[file:working/clock-display-references/][working/clock-display-references/]].
+
+*** 2026-07-19 Sun @ 04:36:26 -0500 Folded clock-panel interaction direction
+The clock-panel handoff settled the prior open question: UTC belongs only to
+the time ring, while the date ring is date-only. The existing task is therefore
+a focused follow-up, not a two-line restoration of the old combined ring.
+** DONE [#C] Notification sound loudness :chore:audio:quick:solo:
+CLOSED: [2026-07-19 Sun]
+Shipped dotfiles 808ca23: NOTIFY_VOLUME default 65536->39322 (0.6 gain) in both notify copies.
+Reduce notification-sound playback loudness by 40% (0.6 gain, approximately
+-4.4 dB). Change the =NOTIFY_VOLUME= playback control rather than re-encoding
+the normalized sound files; verify each notification type still plays clearly.
+** DONE [#C] Show the active wired interface in the Waybar network module :feature:waybar:network:
+CLOSED: [2026-07-19 Sun]
+Shipped dotfiles 22867f9: select_device prefers connected wifi -> connected ethernet -> wifi fallback, so a live cable shows the wired glyph+iface instead of Offline.
+When Ethernet is active, replace the offline-WiFi presentation with the wired
+interface glyph and interface name.
+** DONE [#C] Let the clock panel dismiss itself on right click :feature:clock:waybar:
+CLOSED: [2026-07-19 Sun]
+Shipped dotfiles fc9a2b7: secondary-button gesture -> ClockApplication._dismiss hides the open panel. Live-verified with Craig 2026-07-19.
+Make a right click inside the open clock panel toggle it closed. Preserve left
+click for its established interaction; the Waybar time module remains the
+explicit way to reopen the panel.
+** DONE [#C] Make the WiFi toggle connect the best available profile :feature:network:
+CLOSED: [2026-07-19 Sun]
+Shipped dotfiles 9105361: manage.wifi_radio -> _connect_best_saved activates the strongest in-range saved profile on enable; nothing in range falls back to NM autoconnect.
+When enabling WiFi, automatically connect to the highest-priority available
+saved network instead of requiring a panel selection first.
diff --git a/scripts/cmail-setup-finish.sh b/scripts/cmail-setup-finish.sh
index 949023f..bd72499 100755
--- a/scripts/cmail-setup-finish.sh
+++ b/scripts/cmail-setup-finish.sh
@@ -1,28 +1,29 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-or-later
-# cmail-setup-finish.sh — finish Proton Mail Bridge + cmail-action setup after
-# Bridge first-run. Idempotent; safe to re-run after a Bridge cert rotation or
-# a claude-templates re-clone.
+# cmail-setup-finish.sh — finish Proton Mail Bridge setup after Bridge
+# first-run. Idempotent; safe to re-run after a Bridge cert rotation.
#
# Pre-reqs (the script aborts if any are missing):
# - protonmail-bridge installed (archsetup handles it)
# - You have run 'protonmail-bridge --cli', logged in, and quit at least once
# (the script looks for state at ~/.config/protonmail/bridge-v3/)
-# - claude-templates cloned at ~/projects/claude-templates
+# - cmail-action on PATH (rulesets' `make install` links it; session start
+# runs that, so it arrives on its own)
# - dotfiles stowed (~/.config/.cmailpass.gpg present)
#
# What it does:
# 1. Decrypts ~/.config/.cmailpass.gpg → ~/.config/.cmailpass (mode 0600)
# 2. Copies Bridge's self-signed cert → ~/.config/protonbridge.pem
-# 3. Symlinks ~/projects/claude-templates/.ai/scripts/cmail-action.py
-# → ~/.local/bin/cmail-action
-# 4. Removes the leftover ~/.config/autostart/Proton Mail Bridge.desktop
+# 3. Removes the leftover ~/.config/autostart/Proton Mail Bridge.desktop
# stub (it double-launches Bridge alongside the systemd user service
# and throws an "orphan instance" dialog every login)
-# 5. Installs a wait-for-dns drop-in so Bridge doesn't spam
+# 4. Installs a wait-for-dns drop-in so Bridge doesn't spam
# name-resolution errors during the early-boot DNS race
-# 6. Enables + starts the protonmail-bridge user service
-# 7. Verifies Bridge is listening on 127.0.0.1:1143 / :1025
+# 5. Enables + starts the protonmail-bridge user service
+# 6. Verifies Bridge is listening on 127.0.0.1:1143 / :1025
+#
+# It no longer installs cmail-action. That moved to rulesets
+# (claude-templates/bin/), whose `make install` owns the symlink.
set -euo pipefail
@@ -47,9 +48,12 @@ bridge_state="$HOME/.config/protonmail/bridge-v3"
[ -d "$bridge_state" ] \
|| err "Bridge has no state at $bridge_state — run 'protonmail-bridge --cli' and log in first"
-cmail_action_src="$HOME/projects/claude-templates/.ai/scripts/cmail-action.py"
-[ -f "$cmail_action_src" ] \
- || err "cmail-action.py not found at $cmail_action_src — clone claude-templates first"
+# cmail-action is no longer this script's to install. It lives in rulesets at
+# claude-templates/bin/, and rulesets' `make install` links everything there
+# into ~/.local/bin — which every session start runs, so the symlink reaches
+# each machine on its own. Check that it arrived rather than placing it.
+command -v cmail-action >/dev/null 2>&1 \
+ || err "cmail-action not on PATH — run 'make -C ~/code/rulesets install'"
cmailpass_enc="$HOME/.config/.cmailpass.gpg"
[ -f "$cmailpass_enc" ] \
@@ -69,13 +73,7 @@ cert_dst="$HOME/.config/protonbridge.pem"
cp "$cert_src" "$cert_dst"
ok "copied $cert_src → $cert_dst"
-# 4. Symlink cmail-action
-info "symlinking cmail-action"
-mkdir -p "$HOME/.local/bin"
-ln -sf "$cmail_action_src" "$HOME/.local/bin/cmail-action"
-ok "linked $HOME/.local/bin/cmail-action → $cmail_action_src"
-
-# 5. Remove leftover XDG autostart stub
+# 4. Remove leftover XDG autostart stub
# The systemd --user service is the canonical launcher. The autostart .desktop
# starts a second Bridge instance that can't get the lock and pops up an
# "orphan instance" dialog every login.
@@ -88,7 +86,7 @@ else
ok "no autostart stub present"
fi
-# 6. Install wait-for-dns drop-in
+# 5. Install wait-for-dns drop-in
# User-instance systemd doesn't carry network-online.target / nss-lookup.target,
# so the packaged unit's After=network.target doesn't imply DNS readiness.
# Bridge starts before the resolver is up and its first API calls all fail
@@ -107,7 +105,7 @@ ok "wrote $dropin_file"
systemctl --user daemon-reload
ok "reloaded systemd user units"
-# 7. Enable + start systemd user service
+# 6. Enable + start systemd user service
info "enabling protonmail-bridge user service"
was_active=0
systemctl --user is-active --quiet protonmail-bridge.service && was_active=1
@@ -119,7 +117,7 @@ else
ok "service active"
fi
-# 8. Verify
+# 7. Verify
info "verifying Bridge is listening"
listening="$(ss -ltn 2>/dev/null || true)"
missing=""
diff --git a/todo.org b/todo.org
index d43dc3b..d9a8eae 100644
--- a/todo.org
+++ b/todo.org
@@ -45,6 +45,36 @@ below):
input-side-spec.org (DRAFT, four decisions open).
* Archsetup Open Work
+** TODO [#A] Velox still carries the install placeholder passwords :bug:security:velox:
+SCHEDULED: <2026-08-20 Thu>
+:PROPERTIES:
+:CREATED: [2026-08-20 Thu]
+:LAST_REVIEWED: 2026-08-20
+:END:
+The 2026-08-13 reinstall set placeholder credentials and the runbook's Phase 5
+item to replace them (=passwd=, =zfs change-key zroot=) was never ticked.
+Confirmed still live 2026-08-20 via the archangel handoff, which had to hand
+them back to Craig to get into the machine: =welcome1= for the pool, =welcome=
+for the accounts.
+
+So velox's full-disk encryption is currently protected by a dictionary word
+with a digit, on the machine that travels. Anyone who picks it up owns the pool
+and every account on it — the encryption is doing no work at all.
+
+Two commands, both on velox:
+- =passwd= for each account.
+- =zfs change-key zroot= for the pool passphrase. Note this is the ZBM unlock
+ passphrase, so get it right before rebooting.
+
+Grading: *severity-alone carve-out* — this is a security exposure, so the
+frequency row does not discount it (=todo-format.md=). Critical severity: total
+compromise of an encrypted-at-rest laptop from a guessable string, with the
+device leaving the house. = P1 = [#A].
+
+Distinct from the =VERIFY [#A] Rotate the credentials exposed by the 2026-08-09
+dotfiles leak= under the cgit audit — that one covers credentials a crawler
+already took from a public repo. This one is a local default never changed. Both
+are rotation work; neither substitutes for the other.
** TODO [#B] Qt apps render oversized on velox :bug:velox:solo:
:PROPERTIES:
:CREATED: [2026-08-19 Wed]
@@ -269,6 +299,36 @@ of being carried and flexed.
The interim shield is still live (=HandlePowerKey=ignore=), and the escalation
note stands: an EC-level glitch cuts power below systemd regardless of it.
+*** 2026-08-15 Sat @ 23:05:00 -0500 The reseat did happen, and the touchpad came back — this contradicts the 08-17 read
+Recording this because a parallel session concluded on 08-17 that the reseat had
+not happened and the touchpad was still dead. Both halves were done and verified
+that night, so the two accounts disagree and the disagreement should be visible
+rather than silently resolved by whichever session committed last.
+
+What was done: the input-cover ribbon was reseated first, which fixed the
+phantom power button — the 22:09 boot logged zero =Power key pressed= lines
+after Craig flexed the chassis, against nine on the boot before. The touchpad
+did not change, because the input-cover ribbon is not its connector. The 4-pin
+connector beside the printed =TOUCHPAD= label is silkscreened =PIN 1-2 GND /
+PIN 3-4 VCC= — pure power, so it cannot carry i2c or an interrupt. Reseating the
+ribbon that actually crosses to the mainboard fixed it.
+
+Measured, not assumed: the touchpad interrupt (=amd_gpio= pin 8) went from 0
+counts across all 24 CPUs to 1795, and =i2c_hid_acpi ... did not ack reset
+within 1000 ms= disappeared from the boot log. Craig confirmed the pointer moved.
+
+*Why the 08-17 probe likely misread it:* it checked for a node under
+=/dev/input/by-path/=. i2c-HID touchpads frequently get no =by-path= symlink
+even when fully working, so its absence is not evidence of a dead interrupt
+line. The falsifiable check is the interrupt count in =/proc/interrupts= while
+the pad is being touched, or the reset message in =dmesg=.
+
+*Left open rather than closed* — velox was refusing ssh at merge time on 08-20,
+so the current state could not be re-verified, and a later regression cannot be
+ruled out. One second of Craig's time settles it: move the pointer. If it works,
+close this; if it does not, the interrupt line went back down and that is new
+information.
+
** DOING [#A] Velox reinstall — DR test of archangel + archsetup :velox:chore:
DEADLINE: <2026-08-15 Sat>
:PROPERTIES:
@@ -634,6 +694,33 @@ and turns a silent no-op into a visible line:
5. =signal-cli listAccounts= non-empty. velox lost its registration, and
because agent-text relays to a hardcoded velox, that breaks the phone
channel for the WHOLE FLEET, not just this machine.
+6. =mbsync --list= parses. The Proton Bridge TLS cert
+ (=~/.config/protonbridge.pem=, referenced by =~/.mbsyncrc=) is generated
+ per *installation*, so it cannot be restored or copied between machines.
+ Its absence aborts the config parse, which kills *every* account — gmail
+ and dmail need no bridge and died anyway. The error names only the missing
+ pem, so "no mail at all" and "this one file is missing" look unrelated.
+ Re-derive it off the running bridge's own handshake, no GUI, no secrets:
+ =openssl s_client -connect 127.0.0.1:1143 -starttls imap -showcerts </dev/null | sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' > ~/.config/protonbridge.pem=
+7. The bridge password (=~/.config/.cmailpass=) is per-install too. It is a
+ real file rather than a stow symlink, so it survived the rebuild holding
+ the *previous* install's value — worse than absent, because it looks
+ right. Diagnostic trap: the bridge answers a wrong password with =no such
+ user=, which reads as "no account signed in" and sends you hunting a login
+ problem that doesn't exist. Never treat =no such user= as evidence about
+ account state.
+
+*The distinction that organizes all seven* (from the .emacs.d handoff
+2026-08-14, inbox): every artifact that broke was generated on the machine by
+an application rather than carried by git, stow, or dotfiles. But they split
+two ways, and conflating them is what produces a file that exists, looks
+right, and authenticates against nothing:
+- *Restore* — the old value is still correct: gitignored tooling (1),
+ roam clone state (3), =*.local.el= configs (5).
+- *Re-derive* — the old value is worthless because the application minted a
+ new one: signal-cli registration (4), bridge cert (6), bridge password (7).
+So the checklist wants two columns, not one.
+
Graded [#A] because item 5 is live right now and silently disables
paging, and because the flight is Sunday.
** TODO [#B] Restoring a git repo from backup can resurrect a dangerous diff :bug:
@@ -2903,81 +2990,120 @@ Re-graded =[#C]= → =[#D]= per the bug matrix. There is no defect to fix here;
The maintenance console's coredump metric flagged telega-server on ratio (8 coredumps) and velox (18). Root cause was a version skew: the Dockerized =zevlg/telega-server:latest= is frozen at the 2026-06-05 build while the installed elisp lagged at 20260513, so the newer server's plist parser choked on the older elisp's output. .emacs.d fixed it by upgrading telega to 20260706 on both machines (docker kept, =docker pull= is a no-op against the frozen image). Host-coredump pollution should stop. If zevlg later pushes a =:latest= that outruns the installed elisp, the skew and the coredumps recur — the tell is a fresh =tdat_plist_value:500= assertion in =~/.telega/telega-server.log=. The durable escape is a host-native pinned TDLib build, at the cost of an AUR source build.
* Archsetup Resolved
+** DONE [#B] Velox touchpad interrupt line is dead — needs a part or a BIOS fix :bug:velox:hardware:
+CLOSED: [2026-08-15 Sat]
+:PROPERTIES:
+:CREATED: [2026-08-15 Sat]
+:LAST_REVIEWED: 2026-08-15
+:END:
+*Fixed 2026-08-15 23:05 by reseating the correct connector* — a seating fault
+all along, no part needed. Verified at the kernel level on the 23:05 boot: the
+=did not ack reset within 1000 ms= message is gone (clean handshake), and the
+interrupt count went 0 → 1795. Power-key events also zero, so both faults from
+the mainboard swap are closed.
+
+What made this take three attempts is worth keeping: two of the connectors on
+that board were decoys. The input-cover ribbon looked like the obvious suspect
+and fixing it *did* resolve the power button, which made it look like the whole
+answer. Then the 4-pin connector next to the printed =TOUCHPAD= label looked
+like the touchpad's own — and its cable is silkscreened =PIN 1-2 - GND /
+PIN 3-4 - VCC=, four contacts of pure power, incapable of carrying i2c or an
+interrupt. Reading that silkscreen off the photo is what ruled it out and sent
+the search to the ribbon that actually crosses to the mainboard.
+
+The ordered touchpad becomes a spare, which is what Craig wanted from it anyway.
+The diagnostic path below is left intact — it is the reusable part: =dmesg=
+for the i2c-HID reset message and the interrupt count in =/proc/interrupts=
+together separate "device absent" from "device present but its interrupt line is
+open", and a live USB separates hardware from software in two minutes.
+Split from the ribbon-reseat task 2026-08-15 once the reseat fixed the power
+button and left this untouched — they are two faults, not one.
+
+*Diagnosed to the interrupt line specifically, with software eliminated.*
+- The i2c *data* path works. =i2c_hid_acpi= read the HID descriptor, returned
+ the right product ID (=093A:0274=), =hid-multitouch= bound, and input6/7/8/9
+ were created. A descriptor read is a real bus transaction, so the device is
+ electrically present and answering.
+- The *interrupt* path never fires. IRQ 81, =amd_gpio= hwirq 8, level-triggered,
+ =actions=PIXA3854:00= — the handler is correctly registered on the pin the
+ firmware names. Count is 0 across all 24 CPUs, including during active
+ swiping.
+- =dmesg=: =i2c_hid_acpi i2c-PIXA3854:00: device did not ack reset within 1000 ms=.
+ The i2c-HID reset handshake is acknowledged *by the device asserting the
+ interrupt*, so the first operation needing that line already failed at boot,
+ before anything touched the pad. That is why the fault reproduces on any boot
+ in ten seconds.
+- *Software ruled out by live USB.* Same "did not ack reset" message and no
+ pointer movement under Ubuntu's kernel (2026-08-15). Not a driver, not
+ libinput, not Hyprland, not this install.
+
+Three candidates remain, all needing a part or firmware:
+1. Open conductor on the touchpad's own cable or a bad contact at either end.
+ Framework sells "Touchpad Cable" as a discrete spare, so it is separately
+ replaceable — and the input-cover ribbon reseat would not have touched it.
+2. The touchpad module's interrupt output is dead while its i2c slave still
+ answers. Indistinguishable from 1 without swapping parts.
+3. Firmware naming the wrong GPIO. The DSDT says =amd_gpio= pin 8; if this
+ board revision routes the interrupt elsewhere, the kernel watches a pin that
+ never toggles. Plausible because the mainboard is days old to this machine
+ and its firmware already needed the PSR workaround. BIOS is 03.05
+ (2025-10-30); kernel 6.18.44-1-lts.
+
+*The connector that was reseated is NOT the touchpad's — confirmed from the
+board photo.* Craig reseated the 4-pin connector near the printed word
+=TOUCHPAD=. Its cable is silkscreened =PIN 1-2 - GND / PIN 3-4 - VCC= — four
+contacts, all of them power. No clock, no data, no interrupt; almost certainly
+the keyboard backlight feed. An i2c-HID touchpad cannot run through it, so that
+reseat could never have fixed this, and *the free retry remains untried*.
+Photo: [[file:working/velox-touchpad-interrupt/touchpad-module-underside-2026-08-15.jpg][working/velox-touchpad-interrupt/touchpad-module-underside-2026-08-15.jpg]].
+
+Visible on that board: the controller IC marked =PCT3854= (matching the kernel's
+=PIXA3854=), a larger =CON3= carrying a blue-backed ribbon with "26" marked
+beside it, a white ZIF past the Framework QR label, and a further connector at
+the board's end. The one that matters is whichever ribbon physically *leaves the
+input cover and reaches the mainboard* — that is the touchpad cable, and its far
+end is the press-fit connector at the board. Reseat both ends of that one before
+fitting any new part.
+
+*BIOS 04.02 exists but does not look relevant.* Checked 2026-08-15 with velox
+on AC at 90%: fwupd offers 0.0.3.5 → 0.0.4.2. Read the changelog — the only
+touchpad line is haptic-touchpad support for the Laptop 13 *Pro* chassis, and
+this machine has a conventional PixArt =PIXA3854=. The rest is BIOS Setup
+layout, option naming, TPM behavior, iGPU defaults, PMF slider. Nothing about
+GPIO routing or interrupt configuration. So candidate 3's cheap test is weaker
+than it looked when it was filed sight-unseen; still worth doing (unlisted
+fixes happen, and ACPI tables change), just no longer the front-runner.
+Deliberately deferred past the flight — a cleared NVRAM is the failure that
+started this whole rebuild. Boot-entry recovery reference captured at
+[[file:working/velox-reinstall/velox-uefi-boot-entry-reference.org][working/velox-reinstall/velox-uefi-boot-entry-reference.org]].
+
+Order of attack on return, cheapest first: reseat the touchpad's *own* press
+connector at the mainboard (free, untried) → BIOS 04.02 → fit the replacement
+touchpad. Craig's call 2026-08-15: order the parts now anyway, since they are
+worth holding as spares regardless of which candidate wins.
+
+*What to order.* The replacement *Touchpad* ships with the Touchpad Cable
+pre-installed, so that single part covers candidates 1 and 2 together — no need
+to buy both to cover both. A bare Touchpad Cable is worth adding only as a cheap
+spare. The *Input Cover* is a different and more expensive part, and nothing
+points at it: the keyboard works, so the input-cover ribbon is carrying signal.
+Framework's marketplace renders its catalogue in JavaScript, so prices could not
+be read programmatically — search "Touchpad" under Laptop 13 parts.
+
+*Also worth a Framework support ticket* — the touchpad died coincident with
+their mainboard swap, which may put it inside whatever recourse that carries.
+
+Grading: Major severity (a laptop's built-in pointer is entirely dead — the
+counter-argument is that an external mouse is a complete workaround, which
+would make it Minor; I took Major because losing the integrated pointer degrades
+the machine's portability, which is the whole point of the laptop) x every user,
+every time = P1 = [#A]. Filed [#B] rather than [#A] only because an [#A] must
+carry a date and Craig's return date isn't known yet — date it and raise it to
+[#A] when it is.
+
+Workaround in the meantime: Bluetooth mouse, already in use.
-** DONE [#A] Velox boot recovery — no kernel in BE :bug:velox:zfs:
-CLOSED: [2026-07-19 Sun]
-Recovered. Velox boots linux-lts 6.18.38 and is back on the tailnet (up 1d+, /boot holds initramfs-linux-lts.img). The pre-pacman ZFS snapshot rollback restored the kernel from the ZBM recovery shell.
-Velox won't boot: ZBM prompts for the passphrase, unlocks, then reports no bootable environment with a kernel. Cause: an interrupted kernel =-Syu= removed the old kernel and never installed the new one — /mnt/be/boot (from zroot/ROOT/default) holds ONLY intel-ucode.img; vmlinuz-linux + both initramfs are gone. /boot lives inside zroot/ROOT/default (no separate boot dataset), so root-dataset snapshots capture it.
-
-Status 2026-07-15: a first rollback attempt did NOT fix it (square zero after reboot) — suspected typo in the snapshot name, so the rollback likely errored and did nothing. NOT verified. Next session: verify state in the ZBM recovery shell BEFORE any reboot.
-
-Recovery lever: the pre-pacman ZFS snapshot hook (live on velox since 2026-06-29) snapshots zroot/ROOT/default@pre-pacman_<ts> before every pacman transaction. The newest =pre-pacman_<ts>= predating the failed upgrade holds the intact old kernel — roll back to it.
-Morning steps (Craig at velox ZBM → recovery shell, Ctrl+R):
-#+begin_src sh
-# 1. pool writable + key loaded
-zpool get readonly zroot
-zfs get -H -o value keystatus zroot/ROOT/default
-# if readonly=on: zpool export zroot && zpool import -f -N zroot
-# if keystatus=unavailable: zfs load-key zroot
-
-# 2. list snapshots — COPY THE EXACT NAME (the typo bit here last time)
-zfs list -t snapshot -o name,creation zroot/ROOT/default | grep pre-pacman
-
-# 3. see current /boot state (read-only mount)
-umount /mnt/be 2>/dev/null; mkdir -p /mnt/be
-mount -t zfs -o zfsutil,ro zroot/ROOT/default /mnt/be
-ls -la /mnt/be/boot
-
-# 4. if /boot still shows only intel-ucode.img: redo rollback with the exact name
-umount /mnt/be 2>/dev/null
-zfs rollback -r zroot/ROOT/default@pre-pacman_<EXACT-TS> # -r, NOT -R
-
-# 5. VERIFY before reboot — remount RO, confirm the kernel is back
-mount -t zfs -o zfsutil,ro zroot/ROOT/default /mnt/be
-ls -la /mnt/be/boot # MUST show vmlinuz-linux + initramfs-linux.img
-umount /mnt/be
-
-# 6. only once /boot shows a kernel:
-zpool export zroot && reboot
-#+end_src
-Scope: only zroot/ROOT/default reverts; /home, /var, /media are separate datasets, untouched. After boot: =pacman -Syu= attended, confirm /boot holds vmlinuz-linux + initramfs before any shutdown. Full diagnosis: =inbox/PROCESSED-2026-07-15-0002-from-.emacs.d-velox-boot-failure-handoff.org=; ZBM photo: =inbox/PROCESSED-2026-07-15-0002-from-.emacs.d-PXL_20260715_043758976.jpg= (local on ratio; inbox is gitignored).
-** DONE [#C] Restore date-format scrolling on the waybar date module :feature:waybar:dotfiles:quick:
-CLOSED: [2026-07-19 Sun]
-Shipped dotfiles 9dfe082: date-only ring (ordinal/full/longdate), on-scroll rewired, layout guard flipped. UTC/time stay on the time module.
-Date and time are separate fixed-position controls. The time display cycles its
-own formats, including UTC; the date/calendar control cycles date-only formats
-and never displays a second time. Implement the dedicated format rings,
-tooltip behavior, and tests together in the dotfiles Waybar configuration.
-Reference material for the compact clock/chronograph treatment is filed in
-[[file:working/clock-display-references/][working/clock-display-references/]].
-
-*** 2026-07-19 Sun @ 04:36:26 -0500 Folded clock-panel interaction direction
-The clock-panel handoff settled the prior open question: UTC belongs only to
-the time ring, while the date ring is date-only. The existing task is therefore
-a focused follow-up, not a two-line restoration of the old combined ring.
-** DONE [#C] Notification sound loudness :chore:audio:quick:solo:
-CLOSED: [2026-07-19 Sun]
-Shipped dotfiles 808ca23: NOTIFY_VOLUME default 65536->39322 (0.6 gain) in both notify copies.
-Reduce notification-sound playback loudness by 40% (0.6 gain, approximately
--4.4 dB). Change the =NOTIFY_VOLUME= playback control rather than re-encoding
-the normalized sound files; verify each notification type still plays clearly.
-** DONE [#C] Show the active wired interface in the Waybar network module :feature:waybar:network:
-CLOSED: [2026-07-19 Sun]
-Shipped dotfiles 22867f9: select_device prefers connected wifi -> connected ethernet -> wifi fallback, so a live cable shows the wired glyph+iface instead of Offline.
-When Ethernet is active, replace the offline-WiFi presentation with the wired
-interface glyph and interface name.
-** DONE [#C] Let the clock panel dismiss itself on right click :feature:clock:waybar:
-CLOSED: [2026-07-19 Sun]
-Shipped dotfiles fc9a2b7: secondary-button gesture -> ClockApplication._dismiss hides the open panel. Live-verified with Craig 2026-07-19.
-Make a right click inside the open clock panel toggle it closed. Preserve left
-click for its established interaction; the Waybar time module remains the
-explicit way to reopen the panel.
-** DONE [#C] Make the WiFi toggle connect the best available profile :feature:network:
-CLOSED: [2026-07-19 Sun]
-Shipped dotfiles 9105361: manage.wifi_radio -> _connect_best_saved activates the strongest in-range saved profile on enable; nothing in range falls back to NM autoconnect.
-When enabling WiFi, automatically connect to the highest-priority available
-saved network instead of requiring a panel selection first.
** DONE [#A] Tracked WireGuard private keys in repo — public leak, resolved :bug:security:network:
CLOSED: [2026-07-20 Mon]
Confirmed a live public leak, not just at-risk: git.cjennings.net runs cgit (scan-path=/var/git), so archsetup.git was anonymously cloneable over https. An unauthenticated clone pulled the configs with intact PrivateKeys. Exposed 2026-07-05 (c7b7d16) to 2026-07-20. Regraded to P1/[#A] (public credential exposure, severity-alone carve-out) from the initial [#B].
@@ -3787,6 +3913,12 @@ From the roam inbox (Craig, claimed 2026-07-23): velox needs bringing up to date
Resolved 2026-07-23 by a full sweep over tailscale. The touchpad module was already gone — velox's running waybar (started 01:05, after the reboot) and its tracked config both carry zero =custom/touchpad= entries; what Craig saw was the pre-restow waybar process from before the reboot, and the reboot cleared it. Sweep results: both machines at dotfiles f9b6404 (all three hyprland lock/exit fixes live on velox, config errors clean, =allow_session_lock_restore= reads true); stow restow clean, only the expected skip-worktree files; rulesets pulled to 50fc7ca and =make install= run (agent-text verified working by invoking it — an earlier "MISSING" reading was a PATH artifact of the non-interactive ssh shell, not a real gap); desktop-settings tick timer active; mpvpaper, power-profiles-daemon, gtk4-layer-shell, webkit2gtk all present.
Genuine remaining differences, all per-machine installs rather than sync failures: =cmail-action=, =gcalcli=, and =playwright= aren't installed on velox, and =obsbot-wb-guard.service= isn't enabled there (the OBSBOT lives on ratio). None block anything; file separately if velox should send mail or drive browser tests.
+*** 2026-08-20 Thu @ 09:53:04 -0700 One of those three closed itself; two still stand
+=cmail-action= is on both daily drivers now, and nothing did it deliberately. It moved into rulesets at =claude-templates/bin/=, and rulesets' =make install= links that whole directory into =~/.local/bin= at every session start — so velox picked it up on its own. Verified here: the symlink was written 05:44 this morning by this session's own startup, and the tool runs.
+
+=gcalcli= and =playwright= are still absent on velox, which stays correct until I say velox should send calendar invites or drive browser tests. =obsbot-wb-guard= is still right to be off here; the camera is on ratio.
+
+Leaving the paragraph above as written rather than striking it (rulesets suggested striking). It is the resolution note of a task closed 2026-07-23 and it was accurate that day. Editing a closed record to match today makes it a worse record, and the useful correction is this dated entry, not a redaction.
** DONE [#C] Weather tooltip sunrise and sunset :feature:waybar:weather:quick:solo:
CLOSED: [2026-07-23 Thu]
Shipped 2026-07-23 as dotfiles =de62e9d=. The two rows sit directly below Humidity in the current-conditions block, rendered in the footer's 12-hour format (=%-I:%M %p=) so the tooltip reads one way throughout.
diff --git a/working/velox-reinstall/velox-reinstall-runbook.org b/working/velox-reinstall/velox-reinstall-runbook.org
index 02671e2..0c14946 100644
--- a/working/velox-reinstall/velox-reinstall-runbook.org
+++ b/working/velox-reinstall/velox-reinstall-runbook.org
@@ -22,8 +22,15 @@ Fallback ordering if the test finds a real gap:
the microcode vendor-detection fix (archsetup, 2026-08-08) and was built
without ARCHSETUP_DIR at all.
#+begin_src sh
- cd ~/code/archangel && sudo ARCHSETUP_DIR=~/code/archsetup ./build.sh
+ cd ~/code/archangel && sudo ARCHSETUP_DIR="$HOME/code/archsetup" ./build.sh
#+end_src
+ Two traps in that one line, and either alone silently produces a bare ISO
+ with archsetup absent (archangel, 2026-08-20). The =VAR=value= form is
+ required because sudo's =env_reset= discards an exported variable. And
+ =$HOME= is required because zsh does not expand a tilde on the right-hand
+ side of an assignment — the earlier =ARCHSETUP_DIR=~/code/archsetup= here
+ passed the literal string. build.sh now warns and reports baked/not-baked
+ in its closing summary, so the failure is visible rather than silent.
- [ ] build.sh fixes before the final rebuild (archangel repo):
- rsync exclude for =.ai= (keeps =archsetup/.ai/private-design/= — the
credential audit — off the portable USB stick).
diff --git a/working/velox-reinstall/velox-uefi-boot-entry-reference.org b/working/velox-reinstall/velox-uefi-boot-entry-reference.org
new file mode 100644
index 0000000..8d677da
--- /dev/null
+++ b/working/velox-reinstall/velox-uefi-boot-entry-reference.org
@@ -0,0 +1,75 @@
+#+TITLE: Velox UEFI Boot Entry — Recovery Reference
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-08-15
+
+Captured 2026-08-15 before a BIOS update (03.05 → 04.02) as insurance against
+the update clearing NVRAM. Velox's mainboard swap on 2026-08-13 left exactly
+this kind of empty NVRAM, which is what forced the reinstall — so a cleared
+boot entry is the specific failure worth being able to undo in one command
+rather than reconstruct.
+
+* State at capture
+
+- BIOS: 03.05 (2025-10-30)
+- BootCurrent: 0001
+- BootOrder: 2001,0001,2002,2003 (USB ahead of ZBM — why the Ventoy stick
+ boots when it's inserted)
+- Timeout: 0 seconds
+
+* The entry that matters
+
+=Boot0001* ZFSBootMenu=
+
+| field | value |
+|----------------+----------------------------------------------|
+| ESP part GUID | 8e51b680-f90a-444f-8da5-7e4f93625775 |
+|----------------+----------------------------------------------|
+| partition | 1 (GPT), start 0x800, size 0x100000 |
+|----------------+----------------------------------------------|
+| loader path | =\EFI\ZBM\zfsbootmenu.efi= |
+|----------------+----------------------------------------------|
+| cmdline (data) | =spl_hostid=0x22f8a7a1 zbm.timeout=3= |
+| | =zbm.prefer=zroot zbm.import_policy=hostid= |
+|----------------+----------------------------------------------|
+
+The =data= field is that command line in UTF-16LE, which is how efibootmgr
+passes it as optional data. Recreate with =-u= and the plain string; efibootmgr
+does the encoding.
+
+* Recreating it
+
+From a booted system (or the archangel ISO), with the ESP identified as
+=/dev/nvme0n1p1= or whatever it enumerates as:
+
+#+begin_src bash
+efibootmgr --create \
+ --disk /dev/nvme0n1 --part 1 \
+ --label "ZFSBootMenu" \
+ --loader '\EFI\ZBM\zfsbootmenu.efi' \
+ --unicode 'spl_hostid=0x22f8a7a1 zbm.timeout=3 zbm.prefer=zroot zbm.import_policy=hostid'
+#+end_src
+
+Confirm the disk/part against =lsblk -o NAME,PARTUUID,PARTTYPENAME= first —
+the partition GUID above is the authoritative identifier, not the device name,
+which can enumerate differently.
+
+Then set the order so ZBM is reachable:
+
+#+begin_src bash
+efibootmgr --bootorder 0001,2001,2002,2003
+#+end_src
+
+(The original order put USB first. Keep whichever you prefer; what matters is
+that the ZBM entry exists and is in the list.)
+
+* Other entries (firmware-generated, recreate themselves)
+
+| Boot2001 | EFI USB Device |
+|----------+----------------|
+| Boot2002 | EFI DVD/CDROM |
+|----------+----------------|
+| Boot2003 | EFI Network |
+|----------+----------------|
+
+These are stock firmware entries and come back on their own. Only Boot0001
+carries anything unique.
diff --git a/working/velox-touchpad-interrupt/touchpad-module-underside-2026-08-15.jpg b/working/velox-touchpad-interrupt/touchpad-module-underside-2026-08-15.jpg
new file mode 100644
index 0000000..40c71af
--- /dev/null
+++ b/working/velox-touchpad-interrupt/touchpad-module-underside-2026-08-15.jpg
Binary files differ