constcandidates=db.prepare(`SELECT e.id FROM events e WHERE e.kind!='audit.retention-applied' AND e.time<? AND e.id<=? ${protectedCase}${protectedEvidence} ORDER BY e.id LIMIT ?`).all(cutoff,exportedThrough,options.limit);
// A batch boundary must not leave a retained correlation pointing at an event
// we removed. It is safe to remove children first and their source next run.
constbound=candidates.map(()=>'?').join(',');
constchildren=candidates.length?db.prepare(`SELECT id,json_extract(metadata,'$.sourceEventId') AS source FROM events WHERE kind='sigma.alert' AND id IN (${bound})`).all(...ids):[];
constretainedSources=candidates.length?db.prepare(`SELECT DISTINCT json_extract(metadata,'$.sourceEventId') AS source FROM events WHERE kind='sigma.alert' AND json_extract(metadata,'$.sourceEventId') IN (${bound}) AND id NOT IN (${bound})`).all(...ids,...ids):[];
if(!Number.isInteger(days)||days<0||days>3650)throwError('AUDIT_RETENTION_DAYS must be 0 or 1..3650');
if(days)store.db.exec("CREATE INDEX IF NOT EXISTS audit_retention_time ON events(time,id); CREATE INDEX IF NOT EXISTS audit_sigma_source ON events(json_extract(metadata,'$.sourceEventId')) WHERE kind='sigma.alert';");