feat(FN-5175): thread soft-delete audit context and add reconciliation scri

Adds a reconcile script to recover leaked soft-deleted tasks, threads delete audit context through all callers, and records soft-delete audit events with archive column tracking across core/engine/cli/dashboard, with reliability backstop tests covering caller alignment.

Fusion-Task-Id: FN-5175
This commit is contained in:
Fusion (runfusion.ai)
2026-05-20 02:38:58 -07:00
committed by gsxdsm
parent 6ecef44ab3
commit c9fd41ef26
17 changed files with 656 additions and 21 deletions

View File

@@ -1326,7 +1326,13 @@ export class TriageProcessor {
);
try {
// FN-5129 / FN-5131: split-close must unlink lineage children when deleting the parent.
await this.store.deleteTask(task.id, { removeLineageReferences: true });
await this.store.deleteTask(task.id, {
removeLineageReferences: true,
auditContext: {
agentId: task.assignedAgentId ?? "triage",
runId: generateSyntheticRunId("triage-delete", task.id),
},
});
planLog.log(`✓ ${task.id} split into subtasks (${childTaskIds}) and closed`);
} catch (err: unknown) {
// deleteTask refuses when live tasks still depend on this id.
@@ -1471,7 +1477,13 @@ export class TriageProcessor {
`Converted into subtasks: ${childTaskIds}`,
);
// FN-5129 / FN-5131: split-close must unlink lineage children when deleting the parent.
await this.store.deleteTask(task.id, { removeLineageReferences: true });
await this.store.deleteTask(task.id, {
removeLineageReferences: true,
auditContext: {
agentId: task.assignedAgentId ?? "triage",
runId: generateSyntheticRunId("triage-delete", task.id),
},
});
planLog.log(`✓ ${task.id} split into subtasks (${childTaskIds}) and closed`);
return;
}
@@ -2232,7 +2244,13 @@ export class TriageProcessor {
`Duplicate of ${dupId} — closed`,
);
// Pass removeLineageReferences so a duplicate-close cannot be blocked by lineage children (FN-5129 / FN-5131).
await this.store.deleteTask(task.id, { removeLineageReferences: true });
await this.store.deleteTask(task.id, {
removeLineageReferences: true,
auditContext: {
agentId: task.assignedAgentId ?? "triage",
runId: generateSyntheticRunId("triage-delete", task.id),
},
});
return;
}