From f9556061060fdecda09cfbb45ef4a5ca91744c73 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Wed, 24 Jun 2026 22:12:47 -0700 Subject: [PATCH] FN-6966: flag stale timing metadata in velocity reports Add stale timing context to the weekly test velocity baseline so W26 regressions are not misattributed. - Report timing snapshot age and missing slowest-file paths before the slow-file table. - Persist timing metadata notes in velocity history and regenerate the W26 baseline report. - Cover stale and missing timing metadata warnings with node:test assertions. Files changed: docs/test-velocity-baseline.md | 23 ++- scripts/__tests__/test-velocity-baseline.test.mjs | 26 +++ scripts/test-velocity-baseline.mjs | 65 +++++- scripts/test-velocity-history.json | 231 ++++++++++++++++++++++ 4 files changed, 330 insertions(+), 15 deletions(-) Fusion-Task-Id: FN-6966 Fusion-Task-Lineage: bccac6c2-11c1-4295-b3af-b77dab1748dc --- docs/test-velocity-baseline.md | 23 +- .../__tests__/test-velocity-baseline.test.mjs | 26 ++ scripts/test-velocity-baseline.mjs | 65 ++++- scripts/test-velocity-history.json | 231 ++++++++++++++++++ 4 files changed, 330 insertions(+), 15 deletions(-) diff --git a/docs/test-velocity-baseline.md b/docs/test-velocity-baseline.md index 8fa0fa7449..ce69cb3c4a 100644 --- a/docs/test-velocity-baseline.md +++ b/docs/test-velocity-baseline.md @@ -5,7 +5,7 @@ ## Latest baseline - Cycle: **2026-W26** -- Captured at: **2026-06-23T07:29:54.383Z** +- Captured at: **2026-06-23T18:43:21.941Z** - Timing snapshot: `scripts/test-timings.json` captured at **2026-06-03T23:45:49.672Z** - Quarantine ledger: `scripts/lib/test-quarantine.json` @@ -13,16 +13,21 @@ | Metric | Current | Delta vs previous | |---|---:|---:| -| Merge gate wall-time (`pnpm test:gate`) | 15.9s | +9.5s | -| Boot smoke wall-time (`pnpm smoke:boot`) | 21.1s | +2.3s | -| Changed-only test wall-time (`pnpm test`) | 1m 07s | +57.2s | -| Quarantine / flake count | 0 | -1 | +| Merge gate wall-time (`pnpm test:gate`) | 16.8s | +6.0s | +| Boot smoke wall-time (`pnpm smoke:boot`) | 22.8s | +3.0s | +| Changed-only test wall-time (`pnpm test`) | 19.6s | n/a | +| Quarantine / flake count | 0 | 0 | | Deletion-due quarantines | 0 | n/a | ## Measurement failures - None recorded. +## Timing snapshot notes + +- Timing snapshot is 19 days old; verify slowest-file attribution before treating the table as the current culprit. +- 5 of the listed slowest files no longer exist at the recorded paths: `packages/engine/src/__tests__/reliability-interactions/shared-branch-group-lifecycle.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-automerge-precedence.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-merge-routing.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-promotion-gate.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-promotion.test.ts`. Refresh scripts/test-timings.json before choosing a slow-test rewrite. + ## Slowest 20 test files | Rank | File | Package | Duration | @@ -67,16 +72,16 @@ | Row | Captured at | Gate | Boot smoke | `pnpm test` | Quarantine count | |---|---|---:|---:|---:|---:| -| Previous | 2026-06-22T08:03:10.119Z | 6.5s | 18.8s | 9.8s | 1 | -| Latest | 2026-06-23T07:29:54.383Z | 15.9s | 21.1s | 1m 07s | 0 | -| Delta | — | +9.5s | +2.3s | +57.2s | -1 | +| Previous | 2026-06-23T18:30:19.699Z | 10.8s | 19.8s | unavailable | 0 | +| Latest | 2026-06-23T18:43:21.941Z | 16.8s | 22.8s | 19.6s | 0 | +| Delta | — | +6.0s | +3.0s | n/a | 0 | _Future weekly rows append to `scripts/test-velocity-history.json`; compare the latest row against the previous row before posting to #leads._ ## Post to #leads ```text -FN-6612 weekly test velocity: gate 15.9s (+9.5s), boot smoke 21.1s (+2.3s), pnpm test 1m 07s (+57.2s), quarantine ledger 0 (-1). Slowest file: packages/engine/src/__tests__/reliability-interactions/shared-branch-group-lifecycle.test.ts at 13.9s. Deletion-due quarantines: 0. +FN-6612 weekly test velocity: gate 16.8s (+6.0s), boot smoke 22.8s (+3.0s), pnpm test 19.6s (n/a), quarantine ledger 0 (0). Slowest file: packages/engine/src/__tests__/reliability-interactions/shared-branch-group-lifecycle.test.ts at 13.9s. Deletion-due quarantines: 0. ``` ## How to refresh diff --git a/scripts/__tests__/test-velocity-baseline.test.mjs b/scripts/__tests__/test-velocity-baseline.test.mjs index 8152f67cf4..80f67218fb 100644 --- a/scripts/__tests__/test-velocity-baseline.test.mjs +++ b/scripts/__tests__/test-velocity-baseline.test.mjs @@ -9,6 +9,7 @@ import { measureCommands, readQuarantineCount, renderReport, + timingSnapshotNotes, topSlowestFiles, } from "../test-velocity-baseline.mjs"; @@ -58,6 +59,29 @@ describe("topSlowestFiles", () => { }); }); +describe("timingSnapshotNotes", () => { + it("warns when slowest-file rows are stale or point at missing paths", () => { + const rootDir = tempRoot(); + try { + const notes = timingSnapshotNotes({ + rootDir, + now: new Date("2026-06-23T12:00:00.000Z"), + timingSnapshotCapturedAt: "2026-06-03T12:00:00.000Z", + slowest: [ + { file: "packages/engine/src/__tests__/renamed.test.ts", package: "@fusion/engine", ms: 13_900 }, + ], + }); + + assert.equal(notes.length, 2); + assert.match(notes[0], /20 days old/); + assert.match(notes[1], /renamed\.test\.ts/); + assert.match(notes[1], /Refresh scripts\/test-timings\.json/); + } finally { + rmSync(rootDir, { recursive: true, force: true }); + } + }); +}); + describe("readQuarantineCount", () => { it("counts entries by age bucket and flags deletion-due quarantines after 14 days", () => { const result = readQuarantineCount( @@ -262,6 +286,8 @@ describe("renderReport", () => { assert.match(report, /\| Quarantine \/ flake count \| 2 \| -1 \|/); assert.match(report, /`packages\/a\/src\/__tests__\/slow\.test\.ts` \| @pkg\/a \| 3\.2s/); assert.match(report, /FN-6612 weekly test velocity: gate 12\.0s \(\+2\.0s\)/); + assert.match(report, /## Timing snapshot notes/); + assert.match(report, /No stale or missing timing metadata detected/); }); it("renders seed-baseline trend placeholders when there is no previous entry", () => { diff --git a/scripts/test-velocity-baseline.mjs b/scripts/test-velocity-baseline.mjs index 20bb27bdfd..cabae31a1d 100755 --- a/scripts/test-velocity-baseline.mjs +++ b/scripts/test-velocity-baseline.mjs @@ -140,6 +140,34 @@ export function topSlowestFiles(timingsJson, n = 20) { return rows.slice(0, n); } +/* +FNXC:TestVelocityRegression 2026-06-23-18:58: +The velocity baseline can only guide speed work when its slowest-file table distinguishes real command wall time from stale timing metadata. +Annotate missing paths and old snapshots in the report so renamed `.slow.test.ts` files do not masquerade as the current W26 culprit. +*/ +export function timingSnapshotNotes({ slowest = [], timingSnapshotCapturedAt = null, rootDir = repoRoot, now = new Date() } = {}) { + const notes = []; + const capturedAtDate = toDate(timingSnapshotCapturedAt); + if (capturedAtDate) { + const snapshotAgeDays = Math.floor((now.getTime() - capturedAtDate.getTime()) / 86_400_000); + if (snapshotAgeDays >= 14) { + notes.push( + `Timing snapshot is ${snapshotAgeDays} days old; verify slowest-file attribution before treating the table as the current culprit.`, + ); + } + } + + const missingRows = slowest.filter((row) => !existsSync(path.join(rootDir, row.file))); + if (missingRows.length > 0) { + const sample = missingRows.slice(0, 5).map((row) => `\`${row.file}\``).join(", "); + notes.push( + `${missingRows.length} of the listed slowest files no longer exist at the recorded path${missingRows.length === 1 ? "" : "s"}: ${sample}${missingRows.length > 5 ? ", …" : ""}. Refresh ${DEFAULT_TIMINGS_PATH} before choosing a slow-test rewrite.`, + ); + } + + return notes; +} + function delta(latest, previous, field) { if (!previous || latest?.[field] == null || previous?.[field] == null) return "n/a"; const diff = latest[field] - previous[field]; @@ -157,7 +185,7 @@ function trendCell(current, prior) { return `${diff > 0 ? "+" : ""}${diff}`; } -export function renderReport({ gateMs, bootSmokeMs, testMs, slowest = [], quarantine, capturedAt, previous = null, measurementFailures = [], timingSnapshotCapturedAt = null } = {}) { +export function renderReport({ gateMs, bootSmokeMs, testMs, slowest = [], quarantine, capturedAt, previous = null, measurementFailures = [], timingSnapshotCapturedAt = null, timingNotes = [] } = {}) { const latest = { gateMs: normalizeMs(gateMs), bootSmokeMs: normalizeMs(bootSmokeMs), @@ -175,11 +203,14 @@ export function renderReport({ gateMs, bootSmokeMs, testMs, slowest = [], quaran const failures = measurementFailures.length > 0 ? measurementFailures.map((failure) => `- ${failure.label}: ${failure.status}`).join("\n") : "- None recorded."; + const timingNoteRows = timingNotes.length > 0 + ? timingNotes.map((note) => `- ${note}`).join("\n") + : "- No stale or missing timing metadata detected in the rendered slowest-file rows."; const previousRows = previous ? `| Previous | ${previous.capturedAt ?? "unknown"} | ${formatDuration(previous.gateMs)} | ${formatDuration(previous.bootSmokeMs)} | ${formatDuration(previous.testMs)} | ${previous.quarantineCount ?? "n/a"} |\n| Latest | ${latest.capturedAt} | ${formatDuration(latest.gateMs)} | ${formatDuration(latest.bootSmokeMs)} | ${formatDuration(latest.testMs)} | ${latest.quarantineCount} |\n| Delta | — | ${delta(latest, previous, "gateMs")} | ${delta(latest, previous, "bootSmokeMs")} | ${delta(latest, previous, "testMs")} | ${trendCell(latest.quarantineCount, previous.quarantineCount)} |` : `| Previous | _(seed baseline)_ | — | — | — | — |\n| Latest | ${latest.capturedAt} | ${formatDuration(latest.gateMs)} | ${formatDuration(latest.bootSmokeMs)} | ${formatDuration(latest.testMs)} | ${latest.quarantineCount} |\n| Delta | — | n/a | n/a | n/a | n/a |`; - return `# Test velocity baseline\n\n> Weekly FN-6612 signal-per-second baseline. Measure and report feedback-loop velocity; do **not** add slow tests or wire this report into blocking PR checks. The merge gate remains the existing thin Lint, Typecheck, Build, and Gate path.\n\n## Latest baseline\n\n- Cycle: **${cycle}**\n- Captured at: **${latest.capturedAt}**\n- Timing snapshot: \`${DEFAULT_TIMINGS_PATH}\`${timingSnapshotCapturedAt ? ` captured at **${timingSnapshotCapturedAt}**` : ""}\n- Quarantine ledger: \`${DEFAULT_QUARANTINE_PATH}\`\n\n## Metrics\n\n| Metric | Current | Delta vs previous |\n|---|---:|---:|\n${renderMetricRow("Merge gate wall-time (`pnpm test:gate`)", latest, previous, "gateMs")}\n${renderMetricRow("Boot smoke wall-time (`pnpm smoke:boot`)", latest, previous, "bootSmokeMs")}\n${renderMetricRow("Changed-only test wall-time (`pnpm test`)", latest, previous, "testMs")}\n| Quarantine / flake count | ${latest.quarantineCount} | ${trendCell(latest.quarantineCount, previous?.quarantineCount)} |\n| Deletion-due quarantines | ${quarantine?.deletionDueCount ?? 0} | n/a |\n\n## Measurement failures\n\n${failures}\n\n## Slowest 20 test files\n\n| Rank | File | Package | Duration |\n|---:|---|---|---:|\n${slowRows || "| — | — | — | — |"}\n\n## Quarantine age buckets\n\n| Age bucket | Count |\n|---|---:|\n| 0-6 days | ${quarantine?.byAgeBucket?.["0-6d"] ?? 0} |\n| 7-13 days | ${quarantine?.byAgeBucket?.["7-13d"] ?? 0} |\n| deletion due (>=14 days) | ${quarantine?.byAgeBucket?.deletionDue ?? 0} |\n| unknown/future | ${quarantine?.byAgeBucket?.unknown ?? 0} |\n\n### Deletion-due entries\n\n| File | Quarantined at | Age (days) |\n|---|---:|---:|\n${dueRows || "| — | — | — |"}\n\n## Before / after trend\n\n| Row | Captured at | Gate | Boot smoke | \`pnpm test\` | Quarantine count |\n|---|---|---:|---:|---:|---:|\n${previousRows}\n\n_Future weekly rows append to \`${DEFAULT_HISTORY_PATH}\`; compare the latest row against the previous row before posting to #leads._\n\n## Post to #leads\n\n\`\`\`text\nFN-6612 weekly test velocity: gate ${formatDuration(latest.gateMs)} (${delta(latest, previous, "gateMs")}), boot smoke ${formatDuration(latest.bootSmokeMs)} (${delta(latest, previous, "bootSmokeMs")}), pnpm test ${formatDuration(latest.testMs)} (${delta(latest, previous, "testMs")}), quarantine ledger ${latest.quarantineCount} (${trendCell(latest.quarantineCount, previous?.quarantineCount)}). Slowest file: ${slowest[0]?.file ?? "none"} at ${formatDuration(slowest[0]?.ms)}. Deletion-due quarantines: ${quarantine?.deletionDueCount ?? 0}.\n\`\`\`\n\n## How to refresh\n\n\`\`\`bash\npnpm test:velocity -- --measure --write-report\n\`\`\`\n\nIn measure mode, the script runs a non-measured \`pnpm build\` preflight before timing \`pnpm test:gate\`, \`pnpm smoke:boot\`, or \`pnpm test\`. The preflight time is setup only and is excluded from lane metrics; if it fails, the Measurement failures section records \`Build preflight (pnpm build)\` as the reason. Use \`--skip-build-preflight\` only when the workspace is already built by CI.\n\nReport-only regeneration is cheap and does not run any suite:\n\n\`\`\`bash\npnpm test:velocity\n\`\`\`\n`; + return `# Test velocity baseline\n\n> Weekly FN-6612 signal-per-second baseline. Measure and report feedback-loop velocity; do **not** add slow tests or wire this report into blocking PR checks. The merge gate remains the existing thin Lint, Typecheck, Build, and Gate path.\n\n## Latest baseline\n\n- Cycle: **${cycle}**\n- Captured at: **${latest.capturedAt}**\n- Timing snapshot: \`${DEFAULT_TIMINGS_PATH}\`${timingSnapshotCapturedAt ? ` captured at **${timingSnapshotCapturedAt}**` : ""}\n- Quarantine ledger: \`${DEFAULT_QUARANTINE_PATH}\`\n\n## Metrics\n\n| Metric | Current | Delta vs previous |\n|---|---:|---:|\n${renderMetricRow("Merge gate wall-time (`pnpm test:gate`)", latest, previous, "gateMs")}\n${renderMetricRow("Boot smoke wall-time (`pnpm smoke:boot`)", latest, previous, "bootSmokeMs")}\n${renderMetricRow("Changed-only test wall-time (`pnpm test`)", latest, previous, "testMs")}\n| Quarantine / flake count | ${latest.quarantineCount} | ${trendCell(latest.quarantineCount, previous?.quarantineCount)} |\n| Deletion-due quarantines | ${quarantine?.deletionDueCount ?? 0} | n/a |\n\n## Measurement failures\n\n${failures}\n\n## Timing snapshot notes\n\n${timingNoteRows}\n\n## Slowest 20 test files\n\n| Rank | File | Package | Duration |\n|---:|---|---|---:|\n${slowRows || "| — | — | — | — |"}\n\n## Quarantine age buckets\n\n| Age bucket | Count |\n|---|---:|\n| 0-6 days | ${quarantine?.byAgeBucket?.["0-6d"] ?? 0} |\n| 7-13 days | ${quarantine?.byAgeBucket?.["7-13d"] ?? 0} |\n| deletion due (>=14 days) | ${quarantine?.byAgeBucket?.deletionDue ?? 0} |\n| unknown/future | ${quarantine?.byAgeBucket?.unknown ?? 0} |\n\n### Deletion-due entries\n\n| File | Quarantined at | Age (days) |\n|---|---:|---:|\n${dueRows || "| — | — | — |"}\n\n## Before / after trend\n\n| Row | Captured at | Gate | Boot smoke | \`pnpm test\` | Quarantine count |\n|---|---|---:|---:|---:|---:|\n${previousRows}\n\n_Future weekly rows append to \`${DEFAULT_HISTORY_PATH}\`; compare the latest row against the previous row before posting to #leads._\n\n## Post to #leads\n\n\`\`\`text\nFN-6612 weekly test velocity: gate ${formatDuration(latest.gateMs)} (${delta(latest, previous, "gateMs")}), boot smoke ${formatDuration(latest.bootSmokeMs)} (${delta(latest, previous, "bootSmokeMs")}), pnpm test ${formatDuration(latest.testMs)} (${delta(latest, previous, "testMs")}), quarantine ledger ${latest.quarantineCount} (${trendCell(latest.quarantineCount, previous?.quarantineCount)}). Slowest file: ${slowest[0]?.file ?? "none"} at ${formatDuration(slowest[0]?.ms)}. Deletion-due quarantines: ${quarantine?.deletionDueCount ?? 0}.\n\`\`\`\n\n## How to refresh\n\n\`\`\`bash\npnpm test:velocity -- --measure --write-report\n\`\`\`\n\nIn measure mode, the script runs a non-measured \`pnpm build\` preflight before timing \`pnpm test:gate\`, \`pnpm smoke:boot\`, or \`pnpm test\`. The preflight time is setup only and is excluded from lane metrics; if it fails, the Measurement failures section records \`Build preflight (pnpm build)\` as the reason. Use \`--skip-build-preflight\` only when the workspace is already built by CI.\n\nReport-only regeneration is cheap and does not run any suite:\n\n\`\`\`bash\npnpm test:velocity\n\`\`\`\n`; } function historyEntries(history) { @@ -188,7 +219,7 @@ function historyEntries(history) { return []; } -function createEntry({ capturedAt = new Date().toISOString(), gateMs = null, bootSmokeMs = null, testMs = null, quarantine, slowest, measurementFailures = [], timingSnapshotCapturedAt = null }) { +function createEntry({ capturedAt = new Date().toISOString(), gateMs = null, bootSmokeMs = null, testMs = null, quarantine, slowest, measurementFailures = [], timingSnapshotCapturedAt = null, timingNotes = [] }) { return { capturedAt, gateMs: normalizeMs(gateMs), @@ -198,6 +229,7 @@ function createEntry({ capturedAt = new Date().toISOString(), gateMs = null, boo slowestTop20: slowest, measurementFailures, timingSnapshotCapturedAt, + timingNotes, }; } @@ -283,17 +315,26 @@ export async function measureCommands({ timeoutMs, cwd, stdout, stderr, commandR return { ...results, measurementFailures: failures }; } -function renderFromEntry(entry, previous, quarantine) { +function renderFromEntry(entry, previous, quarantine, { rootDir = repoRoot, now = new Date() } = {}) { + const slowest = entry?.slowestTop20 ?? []; return renderReport({ gateMs: entry?.gateMs, bootSmokeMs: entry?.bootSmokeMs, testMs: entry?.testMs, - slowest: entry?.slowestTop20 ?? [], + slowest, quarantine: quarantine ?? { total: entry?.quarantineCount ?? 0, byAgeBucket: {}, deletionDueEntries: [], deletionDueCount: 0 }, capturedAt: entry?.capturedAt, previous, measurementFailures: entry?.measurementFailures ?? [], timingSnapshotCapturedAt: entry?.timingSnapshotCapturedAt ?? null, + timingNotes: Array.isArray(entry?.timingNotes) + ? entry.timingNotes + : timingSnapshotNotes({ + slowest, + timingSnapshotCapturedAt: entry?.timingSnapshotCapturedAt ?? null, + rootDir, + now, + }), }); } @@ -329,6 +370,12 @@ export async function main(argv = process.argv.slice(2), { rootDir = repoRoot, s slowest, measurementFailures: measured.measurementFailures, timingSnapshotCapturedAt: timings?.capturedAt ?? null, + timingNotes: timingSnapshotNotes({ + slowest, + timingSnapshotCapturedAt: timings?.capturedAt ?? null, + rootDir, + now, + }), }); entries.push(entry); writeJson(DEFAULT_HISTORY_PATH, { entries }, rootDir); @@ -339,9 +386,15 @@ export async function main(argv = process.argv.slice(2), { rootDir = repoRoot, s quarantine, slowest, timingSnapshotCapturedAt: timings?.capturedAt ?? null, + timingNotes: timingSnapshotNotes({ + slowest, + timingSnapshotCapturedAt: timings?.capturedAt ?? null, + rootDir, + now, + }), }); const previous = entries.length > 1 ? entries.at(-2) : null; - const report = renderFromEntry(latest, previous, quarantine); + const report = renderFromEntry(latest, previous, quarantine, { rootDir, now }); if (args.writeReport || args.reportOnly) { writeText(DEFAULT_REPORT_PATH, report, rootDir); diff --git a/scripts/test-velocity-history.json b/scripts/test-velocity-history.json index 8998068cd3..d586debee6 100644 --- a/scripts/test-velocity-history.json +++ b/scripts/test-velocity-history.json @@ -675,6 +675,237 @@ ], "measurementFailures": [], "timingSnapshotCapturedAt": "2026-06-03T23:45:49.672Z" + }, + { + "capturedAt": "2026-06-23T18:30:19.699Z", + "gateMs": 10820, + "bootSmokeMs": 19802, + "testMs": null, + "quarantineCount": 0, + "slowestTop20": [ + { + "file": "packages/engine/src/__tests__/reliability-interactions/shared-branch-group-lifecycle.test.ts", + "ms": 13900, + "package": "@fusion/engine" + }, + { + "file": "packages/core/src/__tests__/agent-store.test.ts", + "ms": 11600, + "package": "@fusion/core" + }, + { + "file": "packages/dashboard/src/__tests__/routes-agents.test.ts", + "ms": 11200, + "package": "@fusion/dashboard" + }, + { + "file": "packages/core/src/__tests__/mission-store.test.ts", + "ms": 10700, + "package": "@fusion/core" + }, + { + "file": "packages/core/src/__tests__/db.test.ts", + "ms": 10100, + "package": "@fusion/core" + }, + { + "file": "packages/dashboard/src/__tests__/routes-git.test.ts", + "ms": 9400, + "package": "@fusion/dashboard" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-automerge-precedence.test.ts", + "ms": 9000, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/merger-ai.test.ts", + "ms": 8700, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-merge-routing.test.ts", + "ms": 8400, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-promotion-gate.test.ts", + "ms": 8400, + "package": "@fusion/engine" + }, + { + "file": "packages/core/src/__tests__/task-documents.test.ts", + "ms": 8300, + "package": "@fusion/core" + }, + { + "file": "packages/engine/src/runtimes/__tests__/in-process-runtime.test.ts", + "ms": 7800, + "package": "@fusion/engine" + }, + { + "file": "packages/cli/src/__tests__/extension.test.ts", + "ms": 7000, + "package": "@runfusion/fusion" + }, + { + "file": "packages/core/src/__tests__/run-audit.test.ts", + "ms": 6900, + "package": "@fusion/core" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-promotion.test.ts", + "ms": 6100, + "package": "@fusion/engine" + }, + { + "file": "packages/dashboard/src/__tests__/routes-planning.test.ts", + "ms": 5600, + "package": "@fusion/dashboard" + }, + { + "file": "packages/core/src/__tests__/store-merge-queue.test.ts", + "ms": 5200, + "package": "@fusion/core" + }, + { + "file": "packages/dashboard/app/components/__tests__/FileEditor.test.tsx", + "ms": 5100, + "package": "@fusion/dashboard" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/integration-worktree-state.test.ts", + "ms": 4900, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/self-healing-already-merged.real-git.test.ts", + "ms": 4900, + "package": "@fusion/engine" + } + ], + "measurementFailures": [ + { + "label": "Changed-only tests (`pnpm test`)", + "status": "exit 1 after 1m 55s" + } + ], + "timingSnapshotCapturedAt": "2026-06-03T23:45:49.672Z" + }, + { + "capturedAt": "2026-06-23T18:43:21.941Z", + "gateMs": 16817, + "bootSmokeMs": 22807, + "testMs": 19604, + "quarantineCount": 0, + "slowestTop20": [ + { + "file": "packages/engine/src/__tests__/reliability-interactions/shared-branch-group-lifecycle.test.ts", + "ms": 13900, + "package": "@fusion/engine" + }, + { + "file": "packages/core/src/__tests__/agent-store.test.ts", + "ms": 11600, + "package": "@fusion/core" + }, + { + "file": "packages/dashboard/src/__tests__/routes-agents.test.ts", + "ms": 11200, + "package": "@fusion/dashboard" + }, + { + "file": "packages/core/src/__tests__/mission-store.test.ts", + "ms": 10700, + "package": "@fusion/core" + }, + { + "file": "packages/core/src/__tests__/db.test.ts", + "ms": 10100, + "package": "@fusion/core" + }, + { + "file": "packages/dashboard/src/__tests__/routes-git.test.ts", + "ms": 9400, + "package": "@fusion/dashboard" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-automerge-precedence.test.ts", + "ms": 9000, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/merger-ai.test.ts", + "ms": 8700, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-merge-routing.test.ts", + "ms": 8400, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-promotion-gate.test.ts", + "ms": 8400, + "package": "@fusion/engine" + }, + { + "file": "packages/core/src/__tests__/task-documents.test.ts", + "ms": 8300, + "package": "@fusion/core" + }, + { + "file": "packages/engine/src/runtimes/__tests__/in-process-runtime.test.ts", + "ms": 7800, + "package": "@fusion/engine" + }, + { + "file": "packages/cli/src/__tests__/extension.test.ts", + "ms": 7000, + "package": "@runfusion/fusion" + }, + { + "file": "packages/core/src/__tests__/run-audit.test.ts", + "ms": 6900, + "package": "@fusion/core" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/branch-group-promotion.test.ts", + "ms": 6100, + "package": "@fusion/engine" + }, + { + "file": "packages/dashboard/src/__tests__/routes-planning.test.ts", + "ms": 5600, + "package": "@fusion/dashboard" + }, + { + "file": "packages/core/src/__tests__/store-merge-queue.test.ts", + "ms": 5200, + "package": "@fusion/core" + }, + { + "file": "packages/dashboard/app/components/__tests__/FileEditor.test.tsx", + "ms": 5100, + "package": "@fusion/dashboard" + }, + { + "file": "packages/engine/src/__tests__/reliability-interactions/integration-worktree-state.test.ts", + "ms": 4900, + "package": "@fusion/engine" + }, + { + "file": "packages/engine/src/__tests__/self-healing-already-merged.real-git.test.ts", + "ms": 4900, + "package": "@fusion/engine" + } + ], + "measurementFailures": [], + "timingSnapshotCapturedAt": "2026-06-03T23:45:49.672Z", + "timingNotes": [ + "Timing snapshot is 19 days old; verify slowest-file attribution before treating the table as the current culprit.", + "5 of the listed slowest files no longer exist at the recorded paths: `packages/engine/src/__tests__/reliability-interactions/shared-branch-group-lifecycle.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-automerge-precedence.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-merge-routing.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-promotion-gate.test.ts`, `packages/engine/src/__tests__/reliability-interactions/branch-group-promotion.test.ts`. Refresh scripts/test-timings.json before choosing a slow-test rewrite." + ] } ] }