[object Object]

← back to Nas Setup

Option B finalizer: drop pipefail + make signature preflight exit-code-based & non-blocking (codesign -dv exits nonzero under root, poisoning the pipefail'd grep guard into a false FATAL) — TK-10547

217e9506fff63937451574d7388669d7b02f5627 · 2026-08-14 09:11:03 -0700 · Steve Abrams

Files touched

Diff

commit 217e9506fff63937451574d7388669d7b02f5627
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Aug 14 09:11:03 2026 -0700

    Option B finalizer: drop pipefail + make signature preflight exit-code-based & non-blocking (codesign -dv exits nonzero under root, poisoning the pipefail'd grep guard into a false FATAL) — TK-10547
---
 scripts/install-optionB-launcher.sh | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/scripts/install-optionB-launcher.sh b/scripts/install-optionB-launcher.sh
index 86987db..6886144 100755
--- a/scripts/install-optionB-launcher.sh
+++ b/scripts/install-optionB-launcher.sh
@@ -15,7 +15,12 @@
 #
 # This script does NOT touch /opt/homebrew/bin/bash, does NOT re-sign the launcher
 # (already adhoc-signed by cycle 8), and is idempotent — safe to re-run.
-set -uo pipefail
+#
+# NOTE: intentionally NO `pipefail` — every guard below is `cmd | grep -q ...` where the
+# TRUTH we want is grep's match, not the upstream exit code. Under root, `codesign -dv`
+# exits non-zero even on a valid signature; with pipefail that non-zero poisons the
+# pipeline and turns a matched grep into a false FATAL. `set -u` stays for unbound-var safety.
+set -u
 
 USER_HOME=/Users/macstudio3
 NAS=$USER_HOME/Projects/nas-setup
@@ -27,8 +32,18 @@ if [ "$(id -u)" -ne 0 ]; then echo "must run as root: sudo bash $0"; exit 1; fi
 # ── 0. sanity: launcher present + signed ──
 say "0. launcher preflight"
 if [ ! -x "$LAUNCHER" ]; then echo "FATAL: $LAUNCHER missing/not executable — run memo Step 0 (cp+codesign) first."; exit 1; fi
-codesign -dv "$LAUNCHER" 2>&1 | grep -q 'adhoc' && echo "OK — $LAUNCHER is ad-hoc signed" \
-  || { echo "FATAL: $LAUNCHER is not ad-hoc signed — re-run: sudo codesign -s - -f $LAUNCHER"; exit 1; }
+# exit-code-based (robust under root), with an output-parse fallback; a failure here is a
+# WARN, not a hard stop — the signature was independently proven present, and the REAL gate
+# is whether Henry gets a verified write in step 3.
+if codesign --verify --strict "$LAUNCHER" 2>/dev/null; then
+  echo "OK — $LAUNCHER signature verifies (--verify)"
+elif codesign -dvv "$LAUNCHER" 2>&1 | grep -qi 'adhoc'; then
+  echo "OK — $LAUNCHER is ad-hoc signed (-dvv)"
+else
+  echo "WARN — codesign could not confirm the signature in this context; proceeding anyway"
+  echo "       (memo Step 0 already ad-hoc-signed it; if the Henry write below is TCC-denied,"
+  echo "        re-sign with: sudo codesign -s - -f $LAUNCHER)"
+fi
 
 # ── 1. install + reload both root daemons ──
 for LABEL in com.steve.nas-dwdump-mirror-root com.steve.nas-realestate-dump-mirror-root; do
@@ -36,8 +51,10 @@ for LABEL in com.steve.nas-dwdump-mirror-root com.steve.nas-realestate-dump-mirr
   DST=/Library/LaunchDaemons/$LABEL.plist
   say "1. install + bootstrap $LABEL"
   # confirm the repo plist really points at the launcher (Option B invariant)
-  if ! /usr/libexec/PlistBuddy -c 'Print :ProgramArguments:0' "$SRC" 2>/dev/null | grep -q "$LAUNCHER"; then
-    echo "FATAL: $SRC ProgramArguments[0] is not $LAUNCHER — repo plist not repointed. Aborting."; exit 1
+  # capture-then-compare (pipefail-immune) instead of a piped grep guard
+  PA0=$(/usr/libexec/PlistBuddy -c 'Print :ProgramArguments:0' "$SRC" 2>/dev/null || true)
+  if [ "$PA0" != "$LAUNCHER" ]; then
+    echo "FATAL: $SRC ProgramArguments[0] is '$PA0', not $LAUNCHER — repo plist not repointed. Aborting."; exit 1
   fi
   install -m 644 -o root -g wheel "$SRC" "$DST" && echo "installed $DST"
   launchctl bootout system/$LABEL 2>/dev/null && echo "booted out old $LABEL" || echo "(was not loaded)"

← a6b1b26 Option B finalizer: one-paste sudo installer to swap both ba  ·  back to Nas Setup  ·  daemon-health: split the last_exit!=0 reason so the morning 3ce75d8 →