Per docs/specs/SUBJECT_MANIFESTS_ON_CATALOGD.md §5 Step 7:
"Subjects whose retention.general_pii_until < now AND status != erased
get marked for review (don't auto-delete; legal needs to approve)."
Per shared::types::BiometricConsent doc-comment (BIPA requirement on
biometric data, max 3 years from last interaction):
"Implementation MUST enforce daily expiration sweep against this field."
Therefore the sweep checks BOTH retention clocks. Reports overdue
subjects to data/_catalog/subjects/_retention_sweep_<YYYY-MM-DD>.jsonl.
Idempotent: subjects already in {Erased, RetentionExpired} are skipped
so daily runs do not append duplicate rows.
Does NOT mutate subject manifests. Legal/operator owns the action
(extend, flip status, schedule erasure).
CLI:
retention_sweep # dry-run (default), stderr only
retention_sweep --apply # also write JSONL report
retention_sweep --as-of <RFC3339> # alternate clock for forecast/test
retention_sweep --storage-root <dir> # default ./data
Tests: 8 unit tests on is_overdue covering all 5 SubjectStatus values,
both clocks, BIPA-only path, and idempotency on already-flagged
subjects.
Live verification (100 subjects in ./data/_catalog/subjects):
- now (2026-05-03): 0 overdue (correct — 4-year retention)
- --as-of 2031-06-01: 100 overdue, 394 days past, jsonl report shape
verified with biometric fields correctly omitted via
serde skip_serializing_if when subject has no biometric clock.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Description
Rust-first object storage system
Languages
TypeScript
38.4%
Rust
35.8%
HTML
13.9%
Python
7.8%
Shell
2.1%
Other
2%