Wildlife Photo Review Workflow

Wildlife Photo Review Workflow

How wildlife photos are triaged, curated, and added to the /wildlife/ gallery. This is the repeatable process to run whenever a new folder of raw photos arrives.

Canonical data model

  • D:\Photos\Wildlife — the canonical folder of curated originals. Only photos that made it into (or were reviewed for) the gallery live here. Originals never enter the git repo.
    • Requirement: every photo selected for the catalog (_data/wildlife.yml) must have its original <file>.JPG in this folder. The build reads originals only from here, so a catalog entry whose original is missing cannot be rebuilt. When adding photos, copy the originals in before building, and treat “catalog ⊆ D:\Photos\Wildlife” as an invariant to verify (no catalog entry may lack its original here).
  • _data/wildlife.yml — single source of truth for the catalog. One entry per photo: file, date, species, scientific, group (bird | mammal | reptile | insect | amphibian | crustacean), location ("" until filled), notes.
  • images/wildlife/{web,thumb}/<file>.jpg — derivatives (1600 px / 400 px), generated by python scripts/build_wildlife_images.py build. The build only processes files listed in the YAML, and reads originals from D:\Photos\Wildlife, so a selected original must be copied there first.
  • After any change, verify: catalog entries == web derivatives == thumb derivatives, with no orphans and nothing missing.

Photo folder layout (as of 2026-07-12)

Raw photos in D:\Photos are organized as D:\Photos\YYYY-MM by capture month (EXIF DateTimeOriginal; file mtime for videos). D:\Photos\Wildlife remains the canonical curated-originals folder (unchanged; the build reads from it). People\ and Scenary\ are unrelated and untouched.

Note: the old dump folders were mislabeled by a year — All_2025_01-04 and All_2025-05 actually held 2026 photos (EXIF and file mtime agree, and it matches the catalog dates). They were split into the 2026 month folders.

Progress so far

Gallery: 176 photos in _data/wildlife.yml (curated candidate set D:\Photos\Wildlife fully reviewed across all months below, plus full-dump finds from the months marked done).

Full-dump triage = scanning the complete monthly dump for wildlife the curated pre-filter missed (that’s what pulled the 16 new species from the June/July dump). Status per month folder:

Month folderFilesFull-dump triage
2026-02325✅ done — 296 stubs triaged (20 already reviewed; 9 videos). The month was mostly a captive zoo visit (02-09, ~121 frames — aviaries, macaws, caged eagles/owls, exotics — all excluded) and a Lincoln Caverns show-cave tour (cave interiors + roosting bats). Remaining wildlife was backyard birds already in the collection (Northern Cardinal, House Finch, Red-bellied/Pileated Woodpecker, Fox Squirrel, chipmunks) and grazing White-tailed Deer. Two borderline candidates raised for review — a distant Yellow-bellied Sapsucker (DSCN0051, new species, rear view) and blurry cave bats (DSCN0294, new group but unidentifiable) — both dropped by user. Net: 0 added.
2026-03539✅ done — 474 stubs triaged (most of the month was a natural-history museum, Fallingwater/Ohiopyle scenery, and indoor portraits); added 5 new species: House Finch (portrait + nesting on anti-bird spikes), House Sparrow (Central Park flock), Northern Mockingbird, Lesser Scaup (male + female, Central Park), Bufflehead (distant record). Corrected 3 sub-agent IDs: a “kestrel” was a Red-tailed Hawk, and two “titmouse”/”Pine Warbler” birds were both Golden-crowned Kinglets.
2026-04674✅ done — 578 stubs triaged (batches 07–10 were an entire captive drive-through safari park, excluded); added 7 new species (Great Blue Heron, Common Merganser, Ruddy Duck, Green-winged Teal, Brown Thrasher, European Starling, Yellowlegs) + 2 family shots (Canada Goose goslings, Mute Swan cygnet). Corrected agent IDs: a “finch” was an Eastern Towhee, “Dowitcher” series was Yellowlegs.
2026-05352✅ done — DSCN1543–1765 (05-10/11 = a safari-park + zoo weekend, mostly captive/excluded) yielded 1 new species (American Goldfinch); DSCN1766+ trip done earlier
2026-06300✅ done (was All_2026_06-16)
2026-07219✅ done — first 24 done earlier; a Florida coastal/Everglades boat trip (DSCN2219–2352, 07-11/12) triaged in a second pass; a night herping outing at the Stormwater Public Access Wildlife Observation Center (DSCN2465–2526, 07-27; this is STA-3/4 / Harold A. Campbell Public Use Area, western Palm Beach County — 26.3385, -80.628 from the FWC boat-ramp record) triaged in a third pass. The boat trip added 5 new species: Bottlenose Dolphin (first cetacean — clean dorsal fin, DSCN2293), Cattle Egret (grassland forager), Eastern Lubber Grasshopper (bark portrait), Least Tern (shell-beach flock — corrected a sub-agent’s “Sandwich Tern” misID), White Peacock butterfly (borderline quality, kept as first record). Added Brown Pelican takeoff frame (already in collection). Excluded a captive dolphin-boat wake sequence’s dupes, ornamental Koi pond, and a “full breach” frame that was an ambiguous surface-roll. Net: +6 photos, +5 species. The night herping outing added 4 new species — Florida Watersnake, Florida Green Watersnake, Pig Frog (2nd amphibian in the collection), and Veiled Chameleon (introduced; 4 frames covering two adult males, a female, and a juvenile — the user picked the frames). Sub-agents ran a quality-only pass; every reptile/amphibian ID was made by the lead model on the originals, which caught an agent calling an adult chameleon a “katydid” and a Pig Frog a “leopard frog”. In-hand shots, motion-blurred snakes, and blown-out flash frames were dropped. Net: +7 photos, +4 species.

Gallery is now 176 photos across 111 species. All month folders triaged — no pending dumps. Also backfilled Chinese (species_zh) names for 12 older species that were missing them (March/April additions).

The review pipeline (run this for each new folder)

1. Generate stubs, excluding already-reviewed photos

For every *.JPG in the new folder, make a 400 px stub — but skip any basename already present in D:\Photos\Wildlife (those were reviewed in a prior round). Also capture EXIF date_taken into a manifest for dedup context.

# 400px stub generator (run once per new folder). Note: on Windows the
# filesystem is case-insensitive, so glob EITHER "*.JPG" OR "*.jpg" — not both,
# or every file is processed twice.
from pathlib import Path
from PIL import Image
SRC = Path(r"D:\Photos\<NEW_FOLDER>"); OUT = Path(r"<scratch>\stubs")
REVIEWED = {p.stem.upper() for p in Path(r"D:\Photos\Wildlife").glob("*.JPG")}
OUT.mkdir(parents=True, exist_ok=True)
for p in sorted(SRC.glob("*.JPG")):
    if p.stem.upper() in REVIEWED: continue
    with Image.open(p) as im:
        im.load(); s = 400/max(im.size)
        (im if s>=1 else im.resize((round(im.width*s),round(im.height*s)), Image.LANCZOS)
         ).convert("RGB").save(OUT/f"{p.stem}.jpg","JPEG",quality=82)

2. Triage with Sonnet sub-agents

Split the stub list into batches of ~31 and dispatch one Sonnet sub-agent per batch (they run in parallel). Each agent reads its batch list + stubs and, for every file, decides:

  • Is it wildlife?
    • INCLUDE free-ranging wild animals of any kind, including free-living introduced/invasive species (e.g., peacocks, iguanas, Egyptian geese, Brown Anoles in Miami).
    • EXCLUDE captive zoo/aquarium animals (enclosures, tanks, signage, exotic non-native captives), pets, and non-animal photos (scenery, people, food, buildings, plants).
  • If wildlife: identify species, rate quality 1–5, note behavior, verdict KEEP / DROP. Relax the quality bar for rare species or rare/interesting behavior. Drop lesser duplicates within the batch.
  • Give the agents the current collection’s species list so they can flag (common in collection) for dedup.

Output: a table File | Date | Wildlife? | Species | Quality | Verdict | Reason plus a tally. Persist each batch’s result to a scratch file (long task — guards against context loss).

3. Aggregate and dedup against the existing collection

The overriding rule is avoid duplicates with what’s already published. In practice, only keep:

  • New species not yet in the catalog, or
  • A clearly superior or distinctly different shot/behavior for a species already present (be conservative — the gallery should not fill with near-dupes).

4. Verify uncertain cases on the original yourself

Do not trust sub-agent IDs blindly for anything going public. Generate ~1200 px versions of the shortlisted candidates and review them directly to: confirm the species, pick the single best frame per species, and catch misidentifications. (This round alone that caught a “Bald Eagle” that was a cormorant, a “Great Blue Heron” that was a female Anhinga, a “Yellow-rumped Warbler” that was a Northern Parula, and a “deer leap” that was feral horses.)

5. Raise borderline photos for human review (required)

Do not silently decide borderline cases. Before adding anything, present a short list to the user for a decision on every photo that is any of:

  • an uncertain species ID (including ones where you overrode a sub-agent),
  • a rare species/behavior kept at low quality (the relaxed-bar cases),
  • a possible duplicate of a species already in the collection,
  • a borderline quality call (obscured, distant, soft) that is otherwise a new species or notable shot.

Give each a one-line reason and a recommended pick, and let the user confirm, swap the frame, or drop it. Only the clearly-good, clearly-new-species photos may be added without asking. (This step matters: past rounds the user swapped in a better frame — e.g. Common Gallinule 2123 over the obscured 2122 — and chose to keep a borderline record the pipeline had set aside.)

6. Add to the collection

  1. Required: copy every selected original from the new folder into D:\Photos\Wildlife first. No catalog entry may exist without its original here (see the invariant in Canonical data model).
  2. Add entries to _data/wildlife.yml (keep it reverse-chronological; location: "" for manual fill later).
  3. python scripts/build_wildlife_images.py build
  4. Verify counts/consistency (catalog == web == thumb, no orphans/missing) and that every catalog file has its original in D:\Photos\Wildlife.
  5. Commit (originals stay out of git; only YAML + derivatives are committed).

Conventions & reminders

  • Quality bar: well-shot, subject prominent, in focus — except relax for rare species and rare behavior (say so in the notes when you do).
  • Invasive vs zoo: free-ranging invasives are in; captive non-native zoo animals are out.
  • Locations are added manually (photos have no GPS EXIF); the map shows only photos whose location resolves to a lat/lng in the locations: table.
  • No Ruby/Jekyll on this machine — verify the GitHub Pages build after pushing rather than rendering locally.