feat(audit-log): daily site SQLite retention purge job (closes unbounded site DB growth)

SiteAuditRetentionService (site-only IHostedService) ticks PurgeExpiredAsync on
InitialDelay(5m)/PurgeInterval(24h, clamped >=1m), cutoff = UtcNow - RetentionDays.
Registered site-only in AddAuditLogHealthMetricsBridge; options bound from
AuditLog:SiteRetention. Per-tick failures swallowed. Added a test-only
PurgeIntervalOverride (mirrors SiteCallAuditOptions) so the ms-cadence tick test
can bypass the 1-min production clamp. Doc updated. (PLAN-04 Task 3, S1/U2)
This commit is contained in:
Joseph Doherty
2026-07-09 06:22:19 -04:00
parent b5271da5c8
commit 74aa872c07
5 changed files with 292 additions and 7 deletions
+13 -3
View File
@@ -409,9 +409,19 @@ MS SQL for direct-write events). Unredacted secrets never persist.
partition switch-out loop. Values are validated to be in
`[30, RetentionDays]`; keys that are not a recognized `AuditChannel` enum name
are rejected at startup.
- **Sites:** daily site job; default 7-day retention (configurable, min 1,
max 90). Respects the hard `ForwardState` invariant — `Pending` rows are
never purged on age alone.
- **Sites:** `SiteAuditRetentionService` (site-only `IHostedService`) runs the
site SQLite retention purge on a timer — first tick after
`AuditLog:SiteRetention:InitialDelay` (default 5 min, short so a daily-recycled
node still purges soon after start), then every
`AuditLog:SiteRetention:PurgeInterval` (default 24 h, clamped to ≥ 1 min).
Each tick calls `ISiteAuditQueue.PurgeExpiredAsync(UtcNow RetentionDays)`,
which deletes eligible rows in one transaction (sidecar first, then the
canonical row) and then runs `PRAGMA incremental_vacuum` to return the freed
pages to the OS. `AuditLog:SiteRetention:RetentionDays` defaults to 7 and is
clamped to `[1, 90]`. Respects the hard `ForwardState` invariant — a `Pending`
row is never purged on age alone; only `Forwarded`/`Reconciled` rows older than
the cutoff are removed. Per-tick failures are swallowed and logged so a transient
SQLite fault never tears the service down.
## Security & Tamper-Evidence