An email/SMS command holds PII: the recipient address (target) and the rendered
body (payload). RetentionService now snapshots outbound commands and, once aged,
redacts target->'[redacted]' and payload->{redacted:true} in place while KEEPING
the template provenance (key/version/locale/hash) — so 'which template version did
we send?' stays answerable after the PII is gone.
- ensureOutboundSnapshots: one snapshot per command, dataClass 'outbound',
archiveAfter==deleteAfter (PII goes straight to redact, no archive phase).
Nullable command scope uses an 'unscoped' tag so the global sweep still reaches it.
- applySweep redact branch switches on targetType; compliance holds honored; audit
'retention.redacted' resourceType 'outbound_command'.
Closes lever #2 of the PII-minimization plan. 3 new + 6 regression tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds IiosRetentionPolicySnapshot (per-interaction frozen lifecycle timestamps)
+ IiosInteraction.dataClass, and a RetentionService whose sweep captures
snapshots then archives (status change) and, past delete_after, redacts content
in place (reusing the Slice-8 tombstone) — never a hard delete. An active
compliance hold blocks both; every action is audited and tenant-scopeable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>