Files
fusion/packages/core/src/task-lineage.ts
Fusion 5386d38567 feat(FN-3990): add task lineage identity and association storage
Adds task lineage storage infrastructure (FN-3990 Step 2), introducing a dedicated `task-lineage.ts` module and related types to track task identity and association relationships, with corresponding database schema and store support plus tests and documentation for the lineage reconciliation process

Fusion-Task-Id: FN-3990
2026-05-11 06:47:43 -07:00

48 lines
1.4 KiB
TypeScript

import { randomUUID } from "node:crypto";
import type {
TaskCommitAssociation,
TaskCommitAssociationConfidence,
TaskCommitAssociationMatchSource,
} from "./types.js";
export const FUSION_TASK_LINEAGE_TRAILER_KEY = "Fusion-Task-Lineage";
export function generateTaskLineageId(): string {
return randomUUID();
}
export function buildTaskLineageTrailer(lineageId: string): string {
return `${FUSION_TASK_LINEAGE_TRAILER_KEY}: ${lineageId}`;
}
export function parseTaskLineageTrailer(message: string): string | undefined {
const lines = message.split(/\r?\n/);
const prefix = `${FUSION_TASK_LINEAGE_TRAILER_KEY}:`;
for (let i = lines.length - 1; i >= 0; i -= 1) {
const line = lines[i]?.trim();
if (line?.startsWith(prefix)) {
const value = line.slice(prefix.length).trim();
if (value) return value;
}
}
return undefined;
}
export function classifyTaskCommitAssociationConfidence(
matchedBy: TaskCommitAssociationMatchSource,
): TaskCommitAssociationConfidence {
if (matchedBy === "canonical-lineage-trailer") return "canonical";
if (matchedBy === "manual-reconciliation") return "ambiguous";
return "legacy";
}
export function normalizeTaskCommitAssociation(
row: TaskCommitAssociation,
): TaskCommitAssociation {
return {
...row,
note: row.note?.trim() || undefined,
confidence: row.confidence ?? classifyTaskCommitAssociationConfidence(row.matchedBy),
};
}