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
This commit is contained in:
gsxdsm
2026-06-24 22:12:47 -07:00
parent 8c734fe230
commit f955606106
4 changed files with 330 additions and 15 deletions

View File

@@ -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

View File

@@ -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", () => {

View File

@@ -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);

View File

@@ -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."
]
}
]
}