---
name: security-evidence
description: Generate the quarterly macOS security-compliance evidence screenshot package for Nathan. Use when asked to create/recreate the evidence zip (e.g. "2026-Q2-Nathan.zip"), refresh the quarterly security screenshots, or capture proof that Screen Lock, FileVault, Gatekeeper, 1Password, About This Mac, or Software Update / auto-update are configured. Produces ~/Downloads/{YEAR}-Q{N}-Nathan.zip with full-screen PNGs named Nathan-#-[Name].png.
metadata:
  triggers:
    - security evidence
    - compliance evidence
    - quarterly screenshots
    - evidence (zip|package)
    - recreate .*-Nathan\.zip
---

# Security Evidence Package (macOS)

Produces the quarterly security-compliance evidence package: a set of full-screen
macOS screenshots proving security controls are enabled, zipped into
`~/Downloads/{YEAR}-Q{N}-Nathan.zip`.

## 1. Determine year, quarter, and output filename

Quarter is the calendar quarter the **current month** falls in. Mapping (the
quarter label is the month its quarter STARTS in):

| Quarter | Start month | Covers months |
|---------|-------------|---------------|
| Q1 | JAN | Jan, Feb, Mar |
| Q2 | APR | Apr, May, Jun |
| Q3 | JUL | Jul, Aug, Sep |
| Q4 | OCT | Oct, Nov, Dec |

Formula: `Q = (month - 1) // 3 + 1`. Output: `~/Downloads/{YEAR}-Q{N}-Nathan.zip`
(e.g. June 2026 → `2026-Q2-Nathan.zip`).

## 2. Check scope against the previous package

List the most recent prior package to see which evidence items were included, and
match that scope (plus anything newly requested):

```bash
ls -t ~/Downloads/*-Nathan.zip | head -1 | xargs unzip -l
```

## 3. Evidence taxonomy

Numbers are fixed; filenames are `Nathan-#-[Name].png`. macOS sources below.

| # | Evidence | macOS source | Capture method |
|---|----------|--------------|----------------|
| 1 | About Your PC / OS info | About This Mac (Apple menu) | §5b |
| 2 | Apps & Features / installed apps | *No clean analog* — Finder `/Applications` or Settings → General → Storage → Applications | manual, only if asked |
| 3 | Virus & Threat Protection | Gatekeeper (Privacy & Security) | search `gatekeeper` → `Gatekeeper` |
| 4 | Screen Saver / lock settings | Lock Screen | search `screen lock` → `Lock Screen` |
| 5 | BitLocker / drive encryption | FileVault | search `encryption` → `FileVault` |
| 6 | Password Manager | 1Password app | §5c |
| 7 | OS Auto-Update enabled | Software Update | search `software update` → `Software Update` |

The standard Mac package is **3,4,5,6** (the historical baseline). Add **1** and
**7** when a full set is wanted. **2** has no faithful macOS equivalent — only do
it if explicitly requested.

## 4. Prerequisites (permissions)

`peekaboo` drives the UI and needs **Screen Recording** + **Accessibility**. These
are granted to the responsible parent process — the terminal app (e.g. Ghostty) —
so `peekaboo` inherits them. Verify:

```bash
peekaboo permissions | grep -E "Screen Recording|Accessibility"
```

If `Not Granted`, these are TCC permissions you cannot set programmatically (SIP
protected). Trigger registration, then ask the user to toggle the terminal app on:

```bash
peekaboo image --path /tmp/_t.png >/dev/null 2>&1; peekaboo move 0 0 >/dev/null 2>&1   # registers in lists
open "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
```

Capture engine: `screencapture -x <out.png>` (full screen, no sound, no cursor).

## 5. Capture each item

Work in a staging dir, e.g. `STAGE=/tmp/{YEAR}-Q{N}-stage` (`mkdir -p`). **Read
every screenshot back** (via the Read tool) to confirm the right pane/state before
saving it under its `Nathan-#-[Name].png` name.

### 5a. System Settings items (3, 4, 5, 7)

Use the bundled helper — it focuses the search box, types the query, clicks the
result, and captures. Path is relative to this skill's folder:

```bash
SK=~/.claude/skills/security-evidence/scripts
"$SK/ss-capture.sh" "screen lock"     "Lock Screen"     "$STAGE/Nathan-4-Screen Lock.png"
"$SK/ss-capture.sh" "encryption"      "FileVault"       "$STAGE/Nathan-5-FileVault.png"
"$SK/ss-capture.sh" "gatekeeper"      "Gatekeeper"      "$STAGE/Nathan-3-Gatekeeper.png"
"$SK/ss-capture.sh" "software update" "Software Update" "$STAGE/Nathan-7-Software Update.png"
```

For **Software Update**, let "Checking for updates…" settle first (re-capture after
~4s) so it reads "Your Mac is up to date" + "Automatic Updates: On".

### 5b. About This Mac (1)

The overview window is owned by a *separate* process, so hide System Settings to
get a clean desktop behind it:

```bash
osascript -e 'tell application "System Settings" to activate'; peekaboo sleep 600 >/dev/null
osascript -e 'tell application "System Events" to tell process "System Settings" to click menu item "About This Mac" of menu 1 of menu bar item 1 of menu bar 1'
peekaboo sleep 2000 >/dev/null
osascript -e 'tell application "System Events" to set visible of process "System Settings" to false'
peekaboo sleep 800 >/dev/null
screencapture -x "$STAGE/Nathan-1-About This Mac.png"
```

### 5c. 1Password (6)

Open it, hide other windows, clear any search, and show the **Profile / All
Accounts** view. **Never leave an individual login's secrets on screen** — if a
vault item is open, press Escape / clear the search first.

```bash
open -a "1Password"; peekaboo sleep 2500 >/dev/null
osascript -e 'tell application "1Password" to activate'; peekaboo sleep 800 >/dev/null
peekaboo hotkey cmd,alt,h >/dev/null    # Hide Others -> clean desktop behind
peekaboo sleep 800 >/dev/null
peekaboo press escape >/dev/null; peekaboo sleep 300 >/dev/null; peekaboo press escape >/dev/null
peekaboo sleep 600 >/dev/null
screencapture -x "$STAGE/Nathan-6-1Password.png"
```

If 1Password is locked (Touch ID / password prompt), the user must unlock it; ask.

## 6. Quality checks (read each capture, then verify)

- **FileVault** toggle shows **On** / recovery key set.
- **Gatekeeper**: "Allow applications from" = **App Store & Known Developers** (or stricter).
- **Software Update**: "Automatic Updates: **On**".
- **Screen Lock**: note the actual values. **Flag** weak posture rather than fixing
  it — e.g. "Require password after screen saver / display off" set to a long delay
  (vs "Immediately"), or display-sleep set to "Never". Do **not** change system
  settings without explicit authorization; report and let the user decide.
- **1Password / About This Mac**: no stray secrets; correct OS version visible.

## 7. Build the zip

`ditto` reproduces Finder's structure (PNGs at root + `__MACOSX` AppleDouble):

```bash
OUT=~/Downloads/{YEAR}-Q{N}-Nathan.zip
rm -f "$OUT"
ditto -c -k --sequesterRsrc "$STAGE" "$OUT"
unzip -t "$OUT" >/dev/null && echo "integrity OK"
unzip -l "$OUT" | grep -E '\.png' | grep -v __MACOSX
```

## 8. Restore the workspace

Un-hide anything that was hidden, and close windows opened for capture:

```bash
osascript -e 'tell application "System Events" to set visible of (every process whose background only is false) to true'
peekaboo app quit "System Settings" >/dev/null 2>&1
```

## Gotchas (learned the hard way)

- **Re-read coordinates live.** The System Settings window moves between launches;
  always `peekaboo see` immediately before each click. Hard-coded coords drift.
- **`--foreground` on clicks.** peekaboo's default click is background delivery and
  won't focus a field or select a row — keystrokes then leak to the sidebar
  (type-select jumps panes).
- **Don't detect the search field by title.** Once populated its title becomes the
  typed text. Detect by geometry (topmost narrow textField). The helper does this.
- **Stray click recovery.** A misclick can pop Launchpad / the Apps grid. Recover
  with two `peekaboo press escape` then re-`activate` System Settings.
- **Captures are full-Retina** (~3420×2224). Background apps must be hidden for a
  clean shot matching the historical package style.
