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:
committed by
gsxdsm
parent
6ecef44ab3
commit
c9fd41ef26
@@ -1154,7 +1154,12 @@ describe("project-aware task command behavior", () => {
|
||||
await runTaskDelete("FN-123", true, "demo-project");
|
||||
|
||||
expect(getTask).toHaveBeenCalledWith("FN-123");
|
||||
expect(deleteTask).toHaveBeenCalledWith("FN-123");
|
||||
expect(deleteTask).toHaveBeenCalledWith("FN-123", expect.objectContaining({
|
||||
auditContext: expect.objectContaining({
|
||||
agentId: "cli",
|
||||
runId: expect.stringMatching(/^synthetic-cli-delete-FN-123-/),
|
||||
}),
|
||||
}));
|
||||
});
|
||||
|
||||
it("runTaskComment, runTaskComments, and runTaskSteer use resolved project store", async () => {
|
||||
@@ -2224,7 +2229,12 @@ describe("runTaskDelete", () => {
|
||||
expect(mockGetTask).toHaveBeenCalledWith("FN-001");
|
||||
expect(mockRlQuestion).not.toHaveBeenCalled();
|
||||
expect(mockDeleteTask).toHaveBeenCalledOnce();
|
||||
expect(mockDeleteTask).toHaveBeenCalledWith("FN-001");
|
||||
expect(mockDeleteTask).toHaveBeenCalledWith("FN-001", expect.objectContaining({
|
||||
auditContext: expect.objectContaining({
|
||||
agentId: "cli",
|
||||
runId: expect.stringMatching(/^synthetic-cli-delete-FN-001-/),
|
||||
}),
|
||||
}));
|
||||
|
||||
const successLine = logSpy.mock.calls.find(
|
||||
(call) => typeof call[0] === "string" && call[0].includes("✓ Deleted"),
|
||||
@@ -2242,7 +2252,12 @@ describe("runTaskDelete", () => {
|
||||
expect(mockRlQuestion).toHaveBeenCalledWith("Are you sure you want to delete FN-001? [y/N] ");
|
||||
expect(mockRlClose).toHaveBeenCalled();
|
||||
expect(mockDeleteTask).toHaveBeenCalledOnce();
|
||||
expect(mockDeleteTask).toHaveBeenCalledWith("FN-001");
|
||||
expect(mockDeleteTask).toHaveBeenCalledWith("FN-001", expect.objectContaining({
|
||||
auditContext: expect.objectContaining({
|
||||
agentId: "cli",
|
||||
runId: expect.stringMatching(/^synthetic-cli-delete-FN-001-/),
|
||||
}),
|
||||
}));
|
||||
|
||||
const successLine = logSpy.mock.calls.find(
|
||||
(call) => typeof call[0] === "string" && call[0].includes("✓ Deleted"),
|
||||
|
||||
@@ -1207,7 +1207,12 @@ export async function runTaskDelete(id: string, force?: boolean, projectName?: s
|
||||
}
|
||||
|
||||
try {
|
||||
await store.deleteTask(id);
|
||||
await store.deleteTask(id, {
|
||||
auditContext: {
|
||||
agentId: "cli",
|
||||
runId: `synthetic-cli-delete-${id}-${Date.now()}`,
|
||||
},
|
||||
});
|
||||
console.log();
|
||||
console.log(` ✓ Deleted ${id}`);
|
||||
console.log();
|
||||
|
||||
@@ -1179,7 +1179,12 @@ export default function kbExtension(pi: ExtensionAPI) {
|
||||
|
||||
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
||||
const store = await getStore(ctx.cwd);
|
||||
const task = await store.deleteTask(params.id);
|
||||
const task = await store.deleteTask(params.id, {
|
||||
auditContext: {
|
||||
agentId: "pi-extension",
|
||||
runId: `synthetic-pi-delete-${params.id}-${Date.now()}`,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: `Deleted ${task.id}` }],
|
||||
|
||||
Reference in New Issue
Block a user