fix: drop false-positive committed_reservation_for_existing_id integrity check
The rule flagged every committed reservation pointing at an existing task ID as an anomaly, but that's the happy-path steady state — reservations transition to `committed` immediately after the task row is inserted, so a committed reservation is always expected to reference an existing task. On any node with task history, the dashboard banner fired with hundreds of "affected" IDs and the store emitted a spurious `[task-id-integrity] anomaly detected` error log. Removes the rule, its type/label/reader, and updates tests (core regression guard now asserts committed reservations don't trigger anomalies; dashboard server-test fixtures use a still-valid anomaly kind). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
6
.changeset/fix-task-id-integrity-false-positive.md
Normal file
6
.changeset/fix-task-id-integrity-false-positive.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@fusion/core": patch
|
||||||
|
"@fusion/dashboard": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Remove false-positive `committed_reservation_for_existing_id` task-ID-integrity check. The rule flagged every committed reservation that pointed at an existing task, but that's the happy-path steady state — a reservation transitions to `committed` immediately after the task row is inserted, so it's always expected to map to an existing ID. The banner was firing on every healthy node with task history.
|
||||||
@@ -99,7 +99,7 @@ describe("detectTaskIdIntegrityAnomalies", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("detects committed reservations that target existing task IDs", () => {
|
it("does not flag committed reservations that point at existing task IDs (the happy-path steady state)", () => {
|
||||||
const db = createDb();
|
const db = createDb();
|
||||||
const now = new Date().toISOString();
|
const now = new Date().toISOString();
|
||||||
insertTask(db, "FN-103");
|
insertTask(db, "FN-103");
|
||||||
@@ -124,13 +124,8 @@ describe("detectTaskIdIntegrityAnomalies", () => {
|
|||||||
|
|
||||||
const report = detectTaskIdIntegrityAnomalies(db);
|
const report = detectTaskIdIntegrityAnomalies(db);
|
||||||
|
|
||||||
expect(report.anomalies).toContainEqual(
|
expect(report.status).toBe("ok");
|
||||||
expect.objectContaining({
|
expect(report.anomalies).toEqual([]);
|
||||||
kind: "committed_reservation_for_existing_id",
|
|
||||||
prefix: "FN",
|
|
||||||
affectedIds: ["FN-103"],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("detects active task rows whose prefix is outside distributed state", () => {
|
it("detects active task rows whose prefix is outside distributed state", () => {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ export type TaskIdIntegrityAnomalyKind =
|
|||||||
| "duplicate_active_id"
|
| "duplicate_active_id"
|
||||||
| "id_in_active_and_archived"
|
| "id_in_active_and_archived"
|
||||||
| "next_sequence_at_or_below_used"
|
| "next_sequence_at_or_below_used"
|
||||||
| "committed_reservation_for_existing_id"
|
|
||||||
| "task_row_outside_known_prefix";
|
| "task_row_outside_known_prefix";
|
||||||
|
|
||||||
export interface TaskIdIntegrityAnomaly {
|
export interface TaskIdIntegrityAnomaly {
|
||||||
@@ -24,7 +23,6 @@ export interface TaskIdIntegrityReport {
|
|||||||
|
|
||||||
type TaskRow = { id: string; source: "tasks" | "archivedTasks" };
|
type TaskRow = { id: string; source: "tasks" | "archivedTasks" };
|
||||||
type StateRow = { prefix: string; nextSequence: number };
|
type StateRow = { prefix: string; nextSequence: number };
|
||||||
type ReservationRow = { prefix: string; taskId: string; status: string };
|
|
||||||
type DuplicateRow = { id: string; duplicateCount: number };
|
type DuplicateRow = { id: string; duplicateCount: number };
|
||||||
|
|
||||||
function parseTaskId(taskId: string): { prefix: string; sequence: number } | null {
|
function parseTaskId(taskId: string): { prefix: string; sequence: number } | null {
|
||||||
@@ -79,20 +77,6 @@ function readStateRows(db: Database): StateRow[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function readCommittedReservations(db: Database): ReservationRow[] {
|
|
||||||
if (!hasTable(db, "distributed_task_id_reservations")) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return db
|
|
||||||
.prepare("SELECT prefix, taskId, status FROM distributed_task_id_reservations WHERE status = 'committed'")
|
|
||||||
.all() as ReservationRow[];
|
|
||||||
} catch {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function readDuplicateActiveIds(db: Database): DuplicateRow[] {
|
function readDuplicateActiveIds(db: Database): DuplicateRow[] {
|
||||||
if (!hasTable(db, "tasks")) {
|
if (!hasTable(db, "tasks")) {
|
||||||
return [];
|
return [];
|
||||||
@@ -215,24 +199,6 @@ export function detectTaskIdIntegrityAnomalies(db: Database): TaskIdIntegrityRep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingIds = new Set(allRows.map((row) => row.id));
|
|
||||||
const committedReservationsByPrefix = new Map<string, string[]>();
|
|
||||||
for (const row of readCommittedReservations(db)) {
|
|
||||||
if (!existingIds.has(row.taskId)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const prefix = row.prefix.trim().toUpperCase() || parseTaskId(row.taskId)?.prefix || "unknown";
|
|
||||||
committedReservationsByPrefix.set(prefix, [...(committedReservationsByPrefix.get(prefix) ?? []), row.taskId]);
|
|
||||||
}
|
|
||||||
for (const [prefix, affectedIds] of committedReservationsByPrefix) {
|
|
||||||
anomalies.push({
|
|
||||||
kind: "committed_reservation_for_existing_id",
|
|
||||||
prefix,
|
|
||||||
affectedIds: uniqueSorted(affectedIds),
|
|
||||||
details: `Committed reservation rows still reference task IDs that already exist for prefix ${prefix}.`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildReport(checkedAt, anomalies);
|
return buildReport(checkedAt, anomalies);
|
||||||
} catch {
|
} catch {
|
||||||
return buildReport(checkedAt, []);
|
return buildReport(checkedAt, []);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ const ANOMALY_LABELS: Record<TaskIdIntegrityReport["anomalies"][number]["kind"],
|
|||||||
duplicate_active_id: "Duplicate active task ID",
|
duplicate_active_id: "Duplicate active task ID",
|
||||||
id_in_active_and_archived: "Task ID present in active and archived storage",
|
id_in_active_and_archived: "Task ID present in active and archived storage",
|
||||||
next_sequence_at_or_below_used: "Allocator next sequence overlaps an existing task ID",
|
next_sequence_at_or_below_used: "Allocator next sequence overlaps an existing task ID",
|
||||||
committed_reservation_for_existing_id: "Committed reservation still points at an existing task ID",
|
|
||||||
task_row_outside_known_prefix: "Task row uses a prefix outside allocator state",
|
task_row_outside_known_prefix: "Task row uses a prefix outside allocator state",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -440,10 +440,10 @@ describe("createServer health and headless mode", () => {
|
|||||||
checkedAt: "2026-05-12T11:00:00.000Z",
|
checkedAt: "2026-05-12T11:00:00.000Z",
|
||||||
anomalies: [
|
anomalies: [
|
||||||
{
|
{
|
||||||
kind: "committed_reservation_for_existing_id",
|
kind: "duplicate_active_id",
|
||||||
prefix: "FN",
|
prefix: "FN",
|
||||||
affectedIds: ["FN-103"],
|
affectedIds: ["FN-103"],
|
||||||
details: "reservation collision",
|
details: "duplicate row",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
@@ -468,10 +468,10 @@ describe("createServer health and headless mode", () => {
|
|||||||
checkedAt: "2026-05-12T11:00:00.000Z",
|
checkedAt: "2026-05-12T11:00:00.000Z",
|
||||||
anomalies: [
|
anomalies: [
|
||||||
{
|
{
|
||||||
kind: "committed_reservation_for_existing_id",
|
kind: "duplicate_active_id",
|
||||||
prefix: "FN",
|
prefix: "FN",
|
||||||
affectedIds: ["FN-103"],
|
affectedIds: ["FN-103"],
|
||||||
details: "reservation collision",
|
details: "duplicate row",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
recommendedAction:
|
recommendedAction:
|
||||||
|
|||||||
Reference in New Issue
Block a user