fix: fail the deploy instead of masking reconcile restore errors

Addresses review feedback on the concurrent-deploy reconcile logic. The
authoritative restore commands in reconcile_owned_paths previously used
`|| true`, so if restoring an owned documentation path failed, the action
would silently stage and commit a deletion and publish broken/missing docs.

- Owned purge/keep paths always exist in the deploy commit, so their
  `git checkout`/`git add` restores are now unmasked: a failure fails the
  job under `set -e` instead of committing a silent deletion. Only the
  best-effort pre-clean `git rm --ignore-unmatch` stays lenient.
- The "latest" yield path only restores from the remote when the remote
  actually publishes it (guarded by `git ls-tree`); otherwise the staged
  removal stands, avoiding an abort on a now-absent pathspec. The
  `git ls-tree` check is unmasked so an invalid FETCH_HEAD fails closed.

Assisted-by: claude-code:claude-4.8-opus
diff --git a/deploy-github-pages/entrypoint.sh b/deploy-github-pages/entrypoint.sh
index 7075198..fe24214 100755
--- a/deploy-github-pages/entrypoint.sh
+++ b/deploy-github-pages/entrypoint.sh
@@ -187,8 +187,19 @@
       # remote's higher version. FETCH_HEAD is the remote tip fetched by the
       # preceding `git pull --rebase`, i.e. the concurrent deploy we rebased onto.
       git rm -rf --ignore-unmatch --quiet -- "${LATEST_OWNED_PATH}" >/dev/null 2>&1 || true
-      git checkout FETCH_HEAD -- "${LATEST_OWNED_PATH}" >/dev/null 2>&1 || true
-      git add -A -- "${LATEST_OWNED_PATH}" >/dev/null 2>&1 || true
+      # Restore the remote's (higher) version IF the remote actually publishes this
+      # path. If it does not (e.g. the higher release skipped "latest"), the
+      # `git rm` above already staged its removal - there is nothing to restore, and
+      # a `git add -A` on the now-absent pathspec would exit 128 and abort. A
+      # genuinely broken FETCH_HEAD makes `git ls-tree` exit nonzero, which - left
+      # unmasked - fails the job under `set -e` rather than being mistaken for
+      # "path absent". A checkout failure on a path the remote DOES have also aborts.
+      local remote_latest
+      remote_latest="$(git ls-tree -r FETCH_HEAD -- "${LATEST_OWNED_PATH}")"
+      if [ -n "${remote_latest}" ]; then
+        git checkout FETCH_HEAD -- "${LATEST_OWNED_PATH}"
+        git add -A -- "${LATEST_OWNED_PATH}"
+      fi
       local kept=() x
       for x in "${OWNED_PURGE_PATHS[@]}"; do
         [ "$x" = "${LATEST_OWNED_PATH}" ] || kept+=("$x")
@@ -198,15 +209,20 @@
     fi
   fi
 
+  # These owned paths are always present in DEPLOY_COMMIT (this deploy published
+  # them), so a restore failure means a genuinely broken repo state. Do NOT mask
+  # checkout/add failures with `|| true`: under `set -e` they must fail the job
+  # rather than silently commit a deletion and publish broken/missing docs. Only
+  # the best-effort pre-clean `git rm` (guarded by --ignore-unmatch) stays lenient.
   for p in "${OWNED_PURGE_PATHS[@]}"; do
     git rm -rf --ignore-unmatch --quiet -- "$p" >/dev/null 2>&1 || true
-    git checkout "$DEPLOY_COMMIT" -- "$p" >/dev/null 2>&1 || true
-    git add -A -- "$p" >/dev/null 2>&1 || true
+    git checkout "$DEPLOY_COMMIT" -- "$p"
+    git add -A -- "$p"
     changed=true
   done
   for p in "${OWNED_KEEP_PATHS[@]}"; do
-    git checkout "$DEPLOY_COMMIT" -- "$p" >/dev/null 2>&1 || true
-    git add -A -- "$p" >/dev/null 2>&1 || true
+    git checkout "$DEPLOY_COMMIT" -- "$p"
+    git add -A -- "$p"
     changed=true
   done
   if [ "$changed" = true ]; then