Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 5 additions & 33 deletions src/queue/processors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ import {
upsertPullRequestFromGitHub,
upsertRepositoryFromGitHub,
} from "../db/repositories";
import { dedupeSignalSnapshots, pruneExpiredRecords } from "../db/retention";
import {
effectiveIssueCapForAccountAge,
isBelowAccountAgeThreshold,
Expand Down Expand Up @@ -414,6 +413,11 @@ import {
maybeRecloseDisallowedReopen,
type ReopenRecloseOutcome,
} from "./review-evasion";
// #4013 step 7: same shim shape for runRetentionPrune -- imported here for processJob's own internal call
// below, and re-exported so test/unit/retention.test.ts and test/unit/selfhost-pg-retention.test.ts's
// existing `import { ... } from "../../src/queue/processors"` keeps working unchanged.
import { runRetentionPrune } from "./retention";
export { runRetentionPrune } from "./retention";
import { isVisualPath } from "../review/visual/paths";
import { buildCapture, fetchShotContentBlock, hasSuccessfulBotCapture, resolveVisualRoutes, type CaptureRoute } from "../review/visual/capture";
import {
Expand Down Expand Up @@ -1047,38 +1051,6 @@ function reuseOrRefreshLiveCiAggregate(
return refreshLiveCiAggregate(env, { repoFullName, facts, prNumber, headSha, baseRef, token, expectedCiContexts, admissionKey });
}

/**
* Run (or dry-run) the data-retention prune across the configured log/snapshot tables, plus the
* signal_snapshots dedup pass (#3810 -- signal_snapshots has no natural dedup, so within its own
* retention window a key can still accumulate many superseded rows), and audit the combined outcome.
* The per-table windows live in RETENTION_POLICY; only append-only/superseded tables are pruned.
*/
export async function runRetentionPrune(
env: Env,
requestedBy: string,
dryRun: boolean,
): Promise<void> {
const results = await pruneExpiredRecords(env, { dryRun });
const dedupeResults = await dedupeSignalSnapshots(env, { dryRun });
const totalDeleted = results.reduce((sum, result) => sum + result.deleted, 0);
const totalDeduped = dedupeResults.reduce((sum, result) => sum + result.deleted, 0);
await recordAuditEvent(env, {
eventType: "retention.prune",
actor: requestedBy,
outcome: dryRun ? "completed" : "success",
detail: dryRun
? `dry-run: ${totalDeleted} row(s) eligible, ${totalDeduped} duplicate signal_snapshots row(s) eligible`
: `pruned ${totalDeleted} row(s), deduped ${totalDeduped} signal_snapshots row(s)`,
metadata: {
dryRun,
totalDeleted,
perTable: Object.fromEntries(results.map((r) => [r.table, r.deleted])),
totalDeduped,
perSignalType: Object.fromEntries(dedupeResults.map((r) => [r.signalType, r.deleted])),
},
});
}

const PUBLIC_MANIFEST_POLICY_FINDING_OVERRIDES: Partial<
Record<
FocusManifestFinding["code"],
Expand Down
38 changes: 38 additions & 0 deletions src/queue/retention.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Data-retention pruning (#4013 step 7 -- extracted from processors.ts, seventh step of the file's own
// module-split sequence, after transient-locks.ts, signal-snapshot.ts, duplicate-detection.ts,
// slop-detection.ts, review-evasion.ts, and ci-resolution.ts). Pure move.

import { recordAuditEvent } from "../db/repositories";
import { dedupeSignalSnapshots, pruneExpiredRecords } from "../db/retention";

/**
* Run (or dry-run) the data-retention prune across the configured log/snapshot tables, plus the
* signal_snapshots dedup pass (#3810 -- signal_snapshots has no natural dedup, so within its own
* retention window a key can still accumulate many superseded rows), and audit the combined outcome.
* The per-table windows live in RETENTION_POLICY; only append-only/superseded tables are pruned.
*/
export async function runRetentionPrune(
env: Env,
requestedBy: string,
dryRun: boolean,
): Promise<void> {
const results = await pruneExpiredRecords(env, { dryRun });
const dedupeResults = await dedupeSignalSnapshots(env, { dryRun });
const totalDeleted = results.reduce((sum, result) => sum + result.deleted, 0);
const totalDeduped = dedupeResults.reduce((sum, result) => sum + result.deleted, 0);
await recordAuditEvent(env, {
eventType: "retention.prune",
actor: requestedBy,
outcome: dryRun ? "completed" : "success",
detail: dryRun
? `dry-run: ${totalDeleted} row(s) eligible, ${totalDeduped} duplicate signal_snapshots row(s) eligible`
: `pruned ${totalDeleted} row(s), deduped ${totalDeduped} signal_snapshots row(s)`,
metadata: {
dryRun,
totalDeleted,
perTable: Object.fromEntries(results.map((r) => [r.table, r.deleted])),
totalDeduped,
perSignalType: Object.fromEntries(dedupeResults.map((r) => [r.signalType, r.deleted])),
},
});
}