#+TITLE: Reinstall gaps, part three — per-install certs and credentials, and one failure that hid the others #+AUTHOR: Craig Jennings * Third handoff today Two earlier notes covered five gaps ([[file:2026-08-14-velox-reinstall-gaps-1.org][the first report]] and [[file:2026-08-14-velox-reinstall-gaps-2.org][the follow-up]]). Email was the last thing broken on velox after the 2026-08-13 rebuild, and it turned up two more — both the same shape, and one of them with a property worth generalizing. Email is fully working now: three accounts, 21,853 messages, 4.0 GB indexed. * Gap 6 — the Proton Bridge TLS cert is per-install, and its absence disabled every account =~/.mbsyncrc= carries =CertificateFile /home/cjennings/.config/protonbridge.pem=. That file did not exist after the rebuild, and it cannot be restored from backup or copied from the other machine: Proton Bridge generates a fresh self-signed cert per installation. Velox's is issued 2026-08-13 23:44 with a different fingerprint from ratio's 2026-01-30 one. *The part worth acting on is the blast radius.* mbsync parses its entire config before doing any work, so a missing =CertificateFile= referenced by *one* account aborts the run for *all* of them. Gmail and dmail need no bridge and no cert, and both were dead anyway. The error names only the missing pem, so the symptom ("no mail at all") and the message ("this one file is missing") look unrelated. Recovery does not need the bridge GUI. The running bridge presents the cert on its own IMAP port, so it can be pulled straight off the handshake: : openssl s_client -connect 127.0.0.1:1143 -starttls imap -showcerts ~/.config/protonbridge.pem That is a two-second, fully scriptable step, which makes it a good candidate for the install rather than a runbook line. * Gap 7 — the bridge password is per-install too, and reports a stale value misleadingly =~/.mbsyncrc= resolves the cmail password with =cat ~/.config/.cmailpass=. That file is plaintext and, unusually for my setup, a real file rather than a stow symlink — so it is not in the dotfiles repo, not encrypted, and not carried to a new machine. The file survived the rebuild but held the *previous* install's password, because the bridge regenerates it per installation. Ratio's and velox's differ by sha256, confirmed today. *The diagnostic trap:* Proton Bridge answers a wrong password with =no such user=. I read that as "the bridge has no account signed in" and went looking for a login problem. The account was configured the whole time. If the install ever validates bridge connectivity, it should not treat =no such user= as evidence about account state. * The generalization Gaps 6 and 7 are the same as 1 through 5, sharpened. Everything that broke in this rebuild was *generated on the machine by an application* rather than carried by git, stow, or the dotfiles repo: | gap | artifact | why it did not travel | | 1 | =.ai/=, =todo.org=, =CLAUDE.md= | gitignored | | 2 | =timers.target.wants= symlinks | written by systemctl enable | | 3 | roam clone state | local working tree | | 4 | signal-cli registration | per-device identity | | 5 | =*.local.el= configs | gitignored | | 6 | bridge TLS cert | per-install, regenerated | | 7 | bridge password | per-install, regenerated | Gaps 6 and 7 add a distinction the earlier note missed. For 1, 3 and 5 the old value is still correct, so *restoring* fixes them. For 4, 6 and 7 the old value is *worthless* — the application has generated a new one, and only *re-deriving* from the live system fixes them. An install that tries to restore these will produce exactly what happened here: a file that exists, looks right, and authenticates against nothing. So the install's post-rebuild checklist wants two columns, not one: what to restore, and what to re-derive. * What the install could do - Re-derive the bridge cert from the running bridge with the =openssl s_client= line above. Scriptable, no GUI, no secrets. - Re-derive the bridge password from the bridge rather than expecting the file to be right, and rewrite =.cmailpass=. (I have filed a task on my side to make =PassCmd= ask the bridge directly, which would remove the file entirely.) - Add a cheap post-rebuild validation that =mbsync --list= parses. Config-parse failures disable every account at once and say nothing about mail, so they are worth catching explicitly rather than via "no new mail" hours later. - More generally: keep the restore list and the re-derive list separate, per the table above. * Unrelated, but noticed while comparing the machines =~/.config/.gmailpass.gpg= and =~/.config/.dmailpass.gpg= resolve to mode 777 in the dotfiles repo, on both machines. They are gpg-encrypted so the contents are safe, but world-writable is wrong for a credential file. That is a dotfiles fix, not an archsetup one — noting it here only because it surfaced in the same pass.