Archive every deletion via a bulk SQL retirement

`retireDeletedArtifacts` used to iterate `deleted.slice(0,
MAX_BASH_PROJECTED_FILES)` and emit no signal for paths past the cap
— a large `rm -r` would leave the 51st row onward visible in the
DocumentCenter with no indication anything was missed. The cap was
inherited from the registration path, where it bounds file-stat
round-trips; retirement is a pure metadata update with no filesystem
cost, so the cap was value-free safety theatre.

New DB surface `archiveWorkProductsByExternalPaths` runs a single
`UPDATE … SET status = 'archived' … WHERE external_id IN (…)
AND status <> 'archived' RETURNING id, external_id` per 500-path
chunk — one round-trip per chunk instead of one per path. The
projector feeds the full `deleted` list in, maps the returned ids
back to `retired` outcomes, and no deletion is left behind regardless
of the run's cleanup fan-out size.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-19 17:23:07 -04:00
1 parent f0c4a66cc1
commit fe808d13a2
3 files changed
+78 -18

No files matched your search

+16 -18
View File
@@ -312,6 +312,10 @@ function projectChangedPaths(
* path. `last_touched_by_run_id` carries the retiring run so the
* provenance timeline records the deletion alongside the earlier
* edits.
*
* Every detected deletion is processed — retirement is a bulk
* `UPDATE … IN (…)` chunked by the DB layer, so a large `rm -r`
* retires the full tail instead of leaving the overflow visible.
*/
function retireDeletedArtifacts(
db: AppDatabase,
@@ -319,24 +323,18 @@ function retireDeletedArtifacts(
deleted: string[],
): ProjectionOutcome[] {
if (deleted.length === 0) return [];
const outcomes: ProjectionOutcome[] = [];
const budget = deleted.slice(0, MAX_BASH_PROJECTED_FILES);
for (const rel of budget) {
const existing = db.findWorkProductByExternalId(
ctx.companyId,
"filesystem",
rel,
ctx.workspaceId,
);
if (!existing) continue;
db.updateWorkProduct(existing.id, ctx.companyId, {
status: "archived",
lastTouchedByRunId: ctx.runId,
workspaceId: ctx.workspaceId,
});
outcomes.push({ kind: "retired", workProductId: existing.id, relativePath: rel });
}
return outcomes;
const archived = db.archiveWorkProductsByExternalPaths({
companyId: ctx.companyId,
workspaceId: ctx.workspaceId,
provider: "filesystem",
paths: deleted,
lastTouchedByRunId: ctx.runId,
});
return archived.map(({ id, externalId }) => ({
kind: "retired",
workProductId: id,
relativePath: externalId,
}));
}
/**