Yay diff question?

When I request to see the diffs in AUR packages while updating via yay, I have yet to see any “-” deletion/replacements … only “+” additions.

These additions include version updates and other housekeeping stuff. Shouldn’t there be a “-” deletion of the previous associated lines? I’ve yet to see such info provided for previously installed packages.

What might I be missing?

You are probably purging your yay cache and losing the old versions.

I wonder how that would be happening? I’m not (knowingly) cleaning out .cache files. How else could I be doing this? :man_shrugging:

When you update an AUR package yay first asks if you want to do a clean build so you should respond ‘no’ and the second question is to show diffs where i always answer ‘all’.

Are you sure this happens when you want to update a package, because as far as I know that only happens when you want to (re)install a package that has already been installed, but maybe I missed something :grinning_face:

It always asks me. :grin:

It always asks me too. And I respond no to clean build (typically) and yes to show diffs… But the diff activity I see is only green ”+” content and never any ”-” … That’s what’s puzzling.

Pebcak?

Strange, because its usually checksums and version. Show screenshots.

Have you changed the default behavior of yay? What does this return:

grep answerclean ~/.config/yay/config.json

Interesting thought! I don’t have a json file, it’s init.lua, but here’s the relevant section:

-- Options
yay.opt.diff_menu   = true
yay.opt.edit_menu   = true    -- REQUIRED: makes yay invoke the editor-gate (aurscan-gate) per PKGBUILD
yay.opt.clean_menu  = true
yay.opt.clean_after = false
yay.opt.sort_by     = "votes"
yay.opt.bottom_up   = false

I have no recollection of ever editing this file so I assume these are all stock settings.

You would only have one if you’d modified the default settings.

Is your yay cache currently populated?

ls -1 --group-directories-first ~/.cache/yay

Yes, ~/.cache/yay is full of entries (… similar to the ~/.config/yay directory)

I could understand not getting any ‘-’ diffs with a (relatively) new package update. But even ones I’ve used for years are showing no “-” diffs when I select [A]ll diffs, only seeing the green “+” additions, including new version nums and shasum, but not any sign of the old ones being replaced. :man_shrugging:

And the build directories in the yay cache all currently have PKGBUILDs in them?

Can you share a screenshot of one of your diffs?

Didn’t check every single one, but within the ~/.cache/yay directory, the many subdirectories that I checked all had PKGBUILD files in them.

Will do and report back … but at the moment, there is “nothing to do” when running a yay update.

Okay, ran yay on another computer and, along with numerous core and extra updates, the only AUR package that needed to be updated was archcanary (which had been installed and updated a number of times already)…

AUR Explicit (1): archcanary-0.1.34-1
:: (1/1) Downloaded PKGBUILD: archcanary
  1 archcanary                       (Installed) (Build Files Exist)
==> Packages to cleanBuild?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==> 
  1 archcanary                       (Installed) (Build Files Exist)
==> Diffs to show?
==> [N]one [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)
==> A
diff --git /home/ejm/.cache/yay/archcanary/PKGBUILD /home/ejm/.cache/yay/archcanary/PKGBUILD
new file mode 100644
index 0000000..12b8ac5
--- /dev/null
+++ /home/ejm/.cache/yay/archcanary/PKGBUILD
@@ -0,0 +1,163 @@
+# Maintainer: musqz <gummy-fang-deputy@duck.com>
+pkgname=archcanary
+pkgver=0.1.34
+pkgrel=1
+pkgdesc="Layered security detection stack for Arch Linux — malicious AUR packages, systemd/eBPF persistence, npm/bun cache poisoning, kernel module tampering"
+arch=('any')
+url="https://github.com/musqz/archcanary"
+license=('MIT')
+depends=('bash' 'pacman')
+optdepends=(
+  'libnotify: desktop alerts on infected scan result'
+  'polkit: privileged remediation commands (allowlist edits, audit-rules/lynis-config writes)'
+  'bpf: bpftool for eBPF rootkit detection'
+  'yay: AUR helper with Lua hook support'
+  'paru: AUR helper with PreBuildCommand hook support'
+  'bash-completion: tab-completion for archcanary/canary flags'
+)
+backup=('etc/archcanary/dkms_allowlist.conf'
+        'etc/archcanary/systemd_allowlist.conf'
+        'etc/archcanary/bpftool_allowlist.conf'
+        'etc/archcanary/autostart_allowlist.conf')
+install=archcanary.install
+source=("$pkgname-$pkgver.tar.gz::https://github.com/musqz/$pkgname/archive/v$pkgver.tar.gz")
+sha256sums=('9af70610b8abf1f54bdb88512bf8e5881ce79066269bc8c29083235ca0d49205')
+
+package() {
+  cd "$srcdir/$pkgname-$pkgver"
+
+  # Stamp the real version into the placeholder install.sh normally sed's at
+  # install time — package() bypasses install.sh entirely, so without this
+  # every installed copy keeps the literal "@VERSION@" and --version shows
+  # "unknown".
+  sed -i "s/@VERSION@/$pkgver/" archcanary.sh
+  sed -i "s/@VERSION@/$pkgver/" man/archcanary.1
+
+  # Main user-facing binary
+  install -Dm755 archcanary.sh    "$pkgdir/usr/bin/archcanary"
+
+  # Interactive terminal menu (replaces the removed yad GUI)
+  install -Dm755 archcanary-tui.sh "$pkgdir/usr/bin/archcanary-tui"
+
+  # Desktop entry launching the interactive menu
+  install -Dm644 configs/archcanary.desktop \
+    "$pkgdir/usr/share/applications/archcanary.desktop"
+
+  # Man page
+  install -Dm644 man/archcanary.1 "$pkgdir/usr/share/man/man1/archcanary.1"
+
+  # Bash completion (archcanary + canary alias)
+  install -Dm644 configs/archcanary-completion.bash \
+    "$pkgdir/usr/share/bash-completion/completions/archcanary"
+  ln -sf archcanary "$pkgdir/usr/share/bash-completion/completions/canary"
+
+  # System lib: scanner + root helper + threat lists (used by the root scan)
+  install -dm755 "$pkgdir/usr/lib/archcanary"
+  install -m755  archcanary.sh         "$pkgdir/usr/lib/archcanary/archcanary.sh"
+  install -m755  lib/archcanary-root-helper "$pkgdir/usr/lib/archcanary/root-helper"
+  for _list in package_list.txt malicious_npm_packages.txt \
+               chaos_rat_packages.txt malicious_russian_spam_packages.txt \
+               community_reports.txt; do
+    install -Dm644 "lists/$_list" "$pkgdir/usr/lib/archcanary/$_list"
+  done
+  install -Dm644 configs/lynis-custom.prf \
+    "$pkgdir/usr/lib/archcanary/lynis-custom.prf"
+  install -Dm644 configs/audit-rules.conf \
+    "$pkgdir/usr/lib/archcanary/audit-rules.conf"
+  # yay Lua hook template — read-only reference copy, never installed to
+  # ~/.config/yay/init.lua automatically (that's a per-user path a pacman
+  # transaction can't reach, and hooks are opt-in either way). Lets an
+  # AUR-only install (no git clone) still have something to `cp`; see
+  # `archcanary --doctor`.
+  install -Dm644 configs/yay-init.lua \
+    "$pkgdir/usr/lib/archcanary/yay-init.lua"
+
+  # Polkit policy (authorises root-helper via pkexec)
+  install -Dm644 configs/org.archcanary.policy \
+    "$pkgdir/usr/share/polkit-1/actions/org.archcanary.policy"
+
+  # Systemd system units (root scan: weekly timer + pacman-triggered path;
+  # scan-all-homes: opt-in weekly sweep of every real local user's home)
+  for _unit in systemd/system/archcanary.service \
+               systemd/system/archcanary.timer \
+               systemd/system/archcanary.path \
+               systemd/system/archcanary-onchange.service \
+               systemd/system/archcanary-scan-all-homes.service \
+               systemd/system/archcanary-scan-all-homes.timer; do
+    install -Dm644 "$_unit" "$pkgdir/usr/lib/systemd/system/$(basename "$_unit")"
+  done
+
+  # Systemd user units (user-scope scan + result notifier)
+  for _unit in systemd/user/archcanary-user.service \
+               systemd/user/archcanary-user.timer \
+               systemd/user/archcanary-notify.path \
+               systemd/user/archcanary-notify.service; do
+    install -Dm644 "$_unit" "$pkgdir/usr/lib/systemd/user/$(basename "$_unit")"
+  done
+
+  # Allowlists — seeded as commented templates; users edit in place. pacman's
+  # backup=() array (see above) preserves local edits across upgrades.
+  install -dm755 "$pkgdir/etc/archcanary"
+  cat > "$pkgdir/etc/archcanary/dkms_allowlist.conf" << 'EOF'
+# DKMS modules to skip during --check-kmod (system-wide allowlist).
+# One module name per line. Everything after # is a comment.
+# Add modules that are known-good but not tracked by pacman.
+#
+# Common examples (uncomment as needed):
+# tuxedo-drivers  # TUXEDO Computers hardware driver
+# v4l2loopback    # virtual camera (OBS, video conferencing)
+# vboxdrv         # VirtualBox host kernel module
+# vmmon           # VMware Workstation
+EOF
+
+  cat > "$pkgdir/etc/archcanary/systemd_allowlist.conf" << 'EOF'
+# systemd units to skip during the systemd persistence check (--check-systemd),
+# system-wide allowlist. One unit name per line. Everything after # is a comment.
+# Add units that are known-good but not tracked by pacman and not vetted by the
+# standard-prefix check (e.g. a self-hosted app installed from an upstream
+# binary release rather than a package). A .timer is matched by its OWN name,
+# not its target .service — allowlist both if you want to silence both findings.
+#
+# Example:
+# forgejo.service  # self-hosted git, installed from upstream binary release
+# forgejo.timer    # only needed if forgejo also ships a persistent timer
+EOF
+
+  cat > "$pkgdir/etc/archcanary/bpftool_allowlist.conf" << 'EOF'
+# eBPF loader binaries to skip during the bpftool LSM-loader check
+# (--check-bpftool), system-wide allowlist. One binary basename per line.
+# Everything after # is a comment.
+# Add loaders that are known-good but not pacman-owned (a self-built or
+# manually-installed security/monitoring tool that legitimately loads LSM
+# eBPF hooks) — matched against the basename of /proc/<pid>/exe.
+#
+# Example:
+# falco  # runtime security monitoring, installed from upstream binary release
+EOF
+
+  cat > "$pkgdir/etc/archcanary/autostart_allowlist.conf" << 'EOF'
+# Names to skip during the XDG autostart check (--check-autostart),
+# system-wide allowlist. One entry per line. Everything after # is a
+# comment. Covers two separate findings within the same check, each with
+# its own matching rule:
+#
+# 1. .desktop Exec= names that are known-good but can't be resolved via
+#    $PATH or a standard system prefix — e.g. a package-private helper
+#    binary the non-PATH fallback (search of /usr/lib, /usr/libexec) still
+#    can't find, or an AppImage/Flatpak export. Matched against the bare
+#    Exec= value exactly as written in the .desktop file (not a resolved
+#    path) — usually just a command name.
+#
+# 2. User systemd service ExecStart= binaries unowned by pacman. Matched
+#    against the ExecStart binary's exact, full path (NOT its basename —
+#    a basename match would let an unrelated binary sharing that name
+#    anywhere on disk slip through undetected). Useful for a package that
+#    ships its user unit via /etc/skel (copied into ~/.config/systemd/user/
+#    at account creation, so pacman never tracks that specific copy even
+#    though the binary itself is a normal pacman-owned file).
+#
+# Examples:
+# zeitgeist-datahub               # desktop activity logging, ships in a non-PATH libdir
+# /usr/bin/eos-update-notifier    # EndeavourOS update notifier, user unit ships via /etc/skel
+EOF
+}
diff --git /home/ejm/.cache/yay/archcanary/archcanary.install /home/ejm/.cache/yay/archcanary/archcanary.install
new file mode 100644
index 0000000..9ea80a6
--- /dev/null
+++ /home/ejm/.cache/yay/archcanary/archcanary.install
@@ -0,0 +1,55 @@
+post_install() {
+  # Seed Lynis's false-positive-suppression profile, but only if lynis is
+  # actually installed and the target has no custom.prf of its own yet —
+  # mirrors install.sh's runtime check, which package() cannot do at build time.
+  if command -v lynis &>/dev/null && [[ ! -f /etc/lynis/custom.prf ]]; then
+    install -Dm644 /usr/lib/archcanary/lynis-custom.prf /etc/lynis/custom.prf
+    echo "  installed: /etc/lynis/custom.prf (Lynis false-positive suppressions — edit to enable)"
+  fi
+
+  # Seed auditd rules, same way, only if auditd is installed and the target
+  # has no ruleset yet — mirrors install.sh's runtime check, which package()
+  # cannot do at build time. Already root here, no sudo needed.
+  if command -v auditctl &>/dev/null; then
+    _audit_cfg=/etc/audit/rules.d/30-archcanary.rules
+    install -d -m 755 /etc/audit/rules.d
+    rm -f /etc/audit/rules.d/30-archcanary.conf /etc/audit/rules.d/archcanary.conf
+    if ! grep -qE '^\s*-[waAbfe]' "$_audit_cfg" 2>/dev/null; then
+      install -m 644 /usr/lib/archcanary/audit-rules.conf "$_audit_cfg"
+      augenrules --load >/dev/null 2>&1 || true
+      echo "  installed: $_audit_cfg (auditd rules — edit with --audit-rules-get/--audit-rules-set)"
+    fi
+    unset _audit_cfg
+  fi
+
+  echo ""
+  echo "==> archcanary installed."
+  echo ""
+  echo "  Enable the automated system scan (runs as root — weekly + on boot + after pacman):"
+  echo "    sudo systemctl enable --now archcanary.timer archcanary.path"
+  echo ""
+  echo "  Enable the user-scope scan and result notifier (run as your user):"
+  echo "    systemctl --user enable --now archcanary-user.timer archcanary-notify.path"
+  echo ""
+  echo "  Optional, machine-wide: weekly scan of every other real local user's"
+  echo "  home too, not just yours (see --scan-all-homes) — off by default:"
+  echo "    sudo systemctl enable --now archcanary-scan-all-homes.timer"
+  echo ""
+  echo "  Run a manual full scan:"
+  echo "    archcanary --refresh --full"
+  echo ""
+  echo "  This package installs the system-wide pieces (binaries, systemd units,"
+  echo "  polkit policy, /etc allowlists). Per-user setup can't be done from here"
+  echo "  since it has to run as YOUR user, not the pacman transaction — run:"
+  echo "    archcanary --doctor"
+  echo "  to see exactly what's still missing (yay hooks, lynis)"
+  echo "  and the precise command to fix each one."
+  echo ""
+  echo "  Optional add-ons: lynis (hardening auditor)."
+  echo "  See: https://github.com/musqz/archcanary"
+  echo ""
+}
+
+post_upgrade() {
+  post_install
+}

You just told yay to cleanbuild archcanary.

Uh oh … When I hit Enter I’m assuming that means the default [N]one. If it means clean build [A]ll then I’ve been misunderstanding the prompts from the get-go.

Which brings us back to pebcak after all! :clown_face:

if you just hit the Enter key the default answer will be “None.” It looks like you typed “1” here.