Add an anonymize path for the retention-bound audit trail (today the repo can only hard-delete).
Scope
AuditRepository.anonymizeByUser β new method: updateMany({ userId }, { $set: { userId: null, ip: '', userAgent: '', metadata: {} } }) (repo exposes only deleteMany today). Use the registry's deterministic-anonymization helper where a stable pseudonym is needed.
- Register in
audit.init.js, axes:['user'], retention:'anonymize' + retentionNote (security-log ground, bounded window β the consumer guide documents the recommended 6-12 month log-retention norm; TTL is a consumer choice): export rows by userId only (never org-scoped β no co-member leak); erase = anonymizeByUser, returns itemsRetained with an explanatory message (keep action + timestamp; never delete the trail).
- Tolerate the audit model being absent when the module is deactivated.
DoD
Depends on: registry leaf v2.
Created via /dev:issue Β· contract v2 2026-07-03
Add an anonymize path for the retention-bound audit trail (today the repo can only hard-delete).
Scope
AuditRepository.anonymizeByUserβ new method:updateMany({ userId }, { $set: { userId: null, ip: '', userAgent: '', metadata: {} } })(repo exposes onlydeleteManytoday). Use the registry's deterministic-anonymization helper where a stable pseudonym is needed.audit.init.js,axes:['user'],retention:'anonymize'+retentionNote(security-log ground, bounded window β the consumer guide documents the recommended 6-12 month log-retention norm; TTL is a consumer choice): export rows byuserIdonly (never org-scoped β no co-member leak); erase =anonymizeByUser, returnsitemsRetainedwith an explanatory message (keepaction+ timestamp; never delete the trail).DoD
anonymizeByUserrepo unit test (idempotent re-run safe).userId-scoped; erase result reports retained rows + reason./verifygreen.Depends on: registry leaf v2.
Created via /dev:issue Β· contract v2 2026-07-03