Sergent renameSync() rotates reports/ -> reports/archive/ at 07:30 UTC daily,
so for ~22h per day the only copy of a fresh scan lives in archive/. The
handler now scans both directories and concatenates with top-level priority
on filename collision. archive/ missing is a silent skip.
Tests : 17/17 in test-curl.sh (11 existing + 6 new for archive coverage).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the SSH/rsync canal between Max's workstation cron and the VPS
for fetching defenseur scan reports. The defenseur-auto orchestrator now
pulls reports/defenseur-X_<date>*.json over HTTPS, reusing HEALTH_TOKEN.
The handler mirrors the style of index.js (HTTP native, no framework),
includes the same isScanReport guard as defenseurs/src/report.ts (filters
out defenseur-auto_*.json run reports), and validates the date param
against /^\d{4}-\d{2}-\d{2}$/ to short-circuit path traversal before any
filesystem access.
Validated by test-curl.sh — 11 cases covering auth, validation, date
filter, isScanReport filter, sort order, GET-only and 404 paths.
Spike: ~/claude-code/.spikes/archived/endpoint-reports-sur-vps-health-api-pour/
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>