| name | photo-metadata-inspector |
| description | Use whenever a user wants to inspect, audit, or check what's hidden in a photo BEFORE publishing or sharing it. Show-and-Tell pattern — reveals every EXIF, GPS, XMP, IPTC, and Photoshop block with privacy-risk classification (CRITICAL/HIGH/MEDIUM/LOW) and plain-English explanations, PLUS detects visible pixel-baked branding (logos/watermarks) that survives metadata scrubbing, PLUS provides reverse-image-search guidance to verify ownership. Generates a 3-page branded PDF report (Before/After comparison, detailed findings, ownership risk) THEN offers three choices (scrub / scrub+watermark / keep as-is). Triggers on phrases like "check this photo", "is this photo safe to share", "does this belong to me", "who owns this image", "inspect for privacy issues", "audit this image", or any photo upload with privacy/ownership intent. Auto-pulls branding from the IMM agent's brand cache. |
Photo Metadata Inspector — Show & Tell
A privacy-first photo agent. Drop a photo → see exactly what's hidden inside → decide what to do about it. Show first, scrub second, never silently.
When this fires
- "Check this photo's metadata"
- "What's hidden in this image?"
- "Is this safe to post?"
- "Inspect this photo for privacy issues"
- "What does this photo reveal about me / my location / my device?"
- "Audit this image before I send it"
- "Show me the EXIF data"
- Any photo upload with privacy-investigation intent
The Show-and-Tell flow (always in this order)
Step 1 — Read and display metadata IMMEDIATELY
The moment a photo is dropped, before doing anything else, read all its metadata and show the user what's there. Be specific and dramatic — privacy is invisible until you make it visible.
import sys
sys.path.insert(0, 'scripts')
from metadata_reader import read_metadata, build_summary
findings = read_metadata('/mnt/user-data/uploads/photo.jpg')
print(build_summary(findings))
The skill classifies each field by privacy risk:
| Tier | Meaning | Examples |
|---|
| CRITICAL | Direct identifier | GPS coordinates, owner name, device serial number |
| HIGH | Narrows identity/location/time | Timestamps, timezone, camera make/model, software used |
| MEDIUM | Combinable risk | Altitude, sub-second precision, exposure settings |
| LOW | Technical-only | Color profile, image dimensions |
Step 2 — Show the findings inline (markdown)
Present findings as a markdown table grouped by risk tier, with the value and why it matters for each field. Make GPS coordinates clickable (Google Maps link).
If GPS is present, lead with: 🌍 GPS LOCATION EXPOSED: 41.0793, -85.1394 → [view on map]
Then a markdown table:
| Risk | Field | Value | Why it matters |
|---|
| 🔴 CRITICAL | GPS / GPSLatitude | 41° 4' 45" N | Exact location where photo was taken |
| 🟠 HIGH | DateTimeOriginal | 2024-08-15 14:32:11 | When photo was taken (down to the second) |
| 🟠 HIGH | Make + Model | Apple, iPhone 15 Pro | Device fingerprint |
| 🟡 MEDIUM | LensInfo | ... | ... |
| ⚪ LOW | ColorSpace | sRGB | Color profile (no privacy risk) |
Step 3 — Build the branded PDF Before/After report
from scrubber import scrub
from report_builder import build_inspection_report
clean_preview = scrub(photo_path, "/tmp/inspector_preview_clean.jpg")
build_inspection_report(
photo_path=photo_path,
clean_photo_path=clean_preview,
findings=findings,
output_path="/mnt/user-data/outputs/photo_inspection_<name>.pdf",
action_taken="inspected",
)
The PDF auto-loads branding from /mnt/user-data/uploads/.imm_brand.json if it exists (same brand cache as the IMM spec agent). Otherwise uses neutral gold-on-dark.
Step 4 — Present the three choices
After showing findings + PDF, ALWAYS end with exactly this prompt structure:
Here's what I found. What would you like me to do?
1. Scrub — Strip all metadata, return a clean copy
2. Scrub + Watermark — Strip metadata AND apply your brand watermark (uses photo-watermark skill)
3. Keep as-is — Return the original unchanged (you decided the metadata is fine)
Wait for the user's reply. Don't act preemptively.
Step 5 — Execute the chosen action
Based on the user's reply:
- Scrub → commit
scrubber.scrub(), save final cleaned photo to /mnt/user-data/outputs/, rebuild PDF with action_taken="scrubbed"
- Scrub + Watermark → call scrubber, then invoke the
photo-watermark skill on the cleaned photo, rebuild PDF with action_taken="scrubbed_watermarked"
- Keep as-is → no file action needed, rebuild PDF with
action_taken="kept_as_is" and a warning banner
Always re-present the final PDF with the action confirmed.
Critical rules
- NEVER scrub before showing the metadata. The whole point of Show-and-Tell is to teach the user what was there. Silent scrubbing defeats the purpose.
- NEVER skip the three-choice prompt. The user owns the decision.
- Always classify by privacy risk — don't just dump a JSON blob of EXIF tags. The "why it matters" column is the value-add.
- Make GPS coordinates a clickable Google Maps link — concrete > abstract. "41.0793, -85.1394" means nothing; clicking through to a satellite view of someone's home address makes it real.
- Brand cache is shared with the IMM agent at
/mnt/user-data/uploads/.imm_brand.json. Don't duplicate the brand-extraction flow here — if no cache, just use neutral defaults.
- The PDF report is the deliverable — both the inline markdown summary AND the PDF should be presented every time.
- If a photo has zero metadata, still produce the report — say "✓ Already clean" and explain what zero metadata means.
Anti-patterns
- ❌ Scrubbing the photo first and saying "I cleaned it for you" — defeats the educational purpose
- ❌ Skipping the PDF and only showing inline markdown — markdown disappears, PDF is the proof
- ❌ Showing all fields as one big undifferentiated list — must be classified by risk
- ❌ Using technical jargon ("GPSLatitudeRef", "FNumber") without explanation — every field needs plain-English "why it matters"
- ❌ Asking for the user's website on first run — this skill uses the IMM agent's cache, doesn't re-prompt
- ❌ Auto-applying a watermark — that's a separate skill (photo-watermark), only invoked if the user picks option 2
File map
scripts/metadata_reader.py — comprehensive metadata extraction + risk classification
scripts/scrubber.py — strips ALL metadata, rebuilds from raw pixels
scripts/report_builder.py — branded PDF Before/After report generator
references/risk_classification.md — full table of EXIF tags and their privacy tiers
Companion skill
If the user chooses "Scrub + Watermark", invoke the photo-watermark skill on the scrubbed photo. The watermark skill is independent — it can also be used standalone for photos that don't need metadata stripping.