Skip to content

perf(core): add __perf__ scaffold + npm run bench + 3 calibrated assertions#53

Open
antnewman wants to merge 3 commits into
SingularityAI-Dev:mainfrom
antnewman:perf/scaffold-with-baselines
Open

perf(core): add __perf__ scaffold + npm run bench + 3 calibrated assertions#53
antnewman wants to merge 3 commits into
SingularityAI-Dev:mainfrom
antnewman:perf/scaffold-with-baselines

Conversation

@antnewman
Copy link
Copy Markdown
Contributor

@antnewman antnewman commented May 7, 2026

Closes #46 partially — this is PR 1 of the four-PR sequence you outlined in the issue. Establishes the perf-assertion discipline without coupling it to any algorithmic fix.

What this adds

  • packages/core/__perf__/_helpers.ts — synthetic linear-chain spec generators
  • packages/core/__perf__/compiler.perf.ts — `compileWorkflow` on a 200-step linear chain (threshold 4500ms)
  • packages/core/__perf__/expression.perf.ts — `evaluate` × 10,000 calls on a varying context (threshold 1000ms)
  • packages/core/__perf__/dag.perf.ts — `resolve` on a 1000-step linear chain (threshold 800ms)
  • packages/core/__perf__/README.md — methodology + how-to-run
  • packages/core/vitest.perf.config.ts — picks up only **/*.perf.ts, single-fork for stable timings
  • Root `package.json` — `npm run bench` wired

Threshold calibration — variance discovered

Your original methodology was 5 runs on main, take worst, ×1.25 headroom. I followed it on first calibration, but re-runs across multiple developer-machine sessions revealed substantial variance — single-shot timings ranged from ~750ms to ~2900ms for compileWorkflow on the same 200-step chain depending on background load. The original ×1.25 thresholds were flaky on a loaded machine.

After two iterations:

  1. First commit (4e10e48): pinned thresholds at worst × 1.25 (1749ms compile, 479ms evaluate, 269ms resolve). Stable on a quiet system, flaky under load.
  2. Calibration fix (ebdcd1a): widened headroom to ×1.5 with thresholds based on worst observed across both quiet and loaded sessions. Result: 1.5× the original headroom factor, thresholds now 4500/1000/800ms. Verified stable across 3 consecutive runs on a loaded developer machine.

The +50% trade-off is justified by the bench being opt-in (npm run bench, not default npm test) — stable execution matters more than tight regression sensitivity. Once the algorithmic fixes in PRs 2-4 land, the assertion margin will widen substantially (~100× for the compiler fix), so proof-of-fix remains strong despite the wider initial headroom.

If you'd prefer a different trade-off (e.g. tighter thresholds + accept some flake on loaded machines, or a --strict flag that uses ×1.25 thresholds), I'll happily revise. Each *.perf.ts file's header documents the calibration data so recalibration is one comment-edit away.

Why 200-step chain on the compiler bench (not 1000)

A 1000-step linear chain takes 127 seconds to compile on main — direct empirical demonstration of Candidate 1's quadratic shape. Useful as a finding, but bench tests can't reasonably take 2 minutes per run. 200-step chain runs in ~1-3s on main, still showing the shape clearly enough that Candidate 1's fix will widen the margin from ~1.5× to ~100× — exactly the proof-of-fix signal you wanted.

Verification

$ npm run bench

 Test Files  3 passed (3)
      Tests  3 passed (3)
   Duration  ~5-15s (varies with load)

Verified stable across 3 consecutive runs. Default npm test is unaffected — `.perf.ts` is outside the default `**/.test.ts` glob.

Two unrelated observations made during this work

Worth raising once #45 has merged (not bundling here):

  1. @logic-md/core only exports ./ from its package.json exports field. When I tried to write a baseline-measurement script that imported resolve directly from ./dist/dag.js, node refused with ERR_PACKAGE_PATH_NOT_EXPORTED. The public-API import (`import { resolve } from '@logic-md/core'`) works because index.ts re-exports. Not a bug, but worth a small docs note for runtime implementers writing their own perf tools.
  2. packages/cli/tests/init.test.ts has 2 tests that fail on Windows checkouts (`should have valid YAML frontmatter in all templates`, `should have markdown content after frontmatter`). The failure is regex ^---\n not matching CRLF line endings. CI on `ubuntu-latest` is unaffected. Not addressing in this PR.

Sequencing — what I'm NOT doing in this PR

Per your sequence comment on #46:

  1. PR 2: compiler fix (Candidate 1). Smallest of the three, biggest user-visible win.
  2. PR 3: expression cache (Candidate 2).
  3. PR 4: DAG sort tightening (Candidate 3).

This PR is just the scaffold. No algorithmic changes. Each follow-up fix can be a small targeted PR that re-runs the bench to widen the margin.

Will open PR 2 (compiler fix) once this is merged.


Summary by cubic

Adds a __perf__ benchmark scaffold for @logic-md/core with three calibrated assertions and an npm run bench command. This is PR 1/4 for #46 to set up an opt-in perf regression net with no algorithm changes.

  • New Features

    • Adds packages/core/__perf__ with helpers and README; benchmarks: compileWorkflow on a 200-step linear chain (<4500ms), evaluate ×10,000 (<1000ms), and resolve on a 1000-step chain (<800ms), using worst-on-main ×1.5 headroom.
    • Adds packages/core/vitest.perf.config.ts to run only **/__perf__/**/*.perf.ts serially for stable timings; wires npm run bench. Default npm test is unchanged.
  • Bug Fixes

    • Makes the ×1.5 calibration multiplier consistent across files and docs.
    • Updates the Vitest v4 config to ensure serial execution for stable timings.

Written for commit 8923135. Summary will update on new commits.

Summary by CodeRabbit

  • Tests
    • Added a performance benchmarking suite covering compilation scaling, DAG resolution scaling, and expression-evaluation throughput. Run via npm run bench.
  • Documentation
    • Added a perf guide documenting how to run benchmarks, the three covered metrics, calibration methodology for thresholds, and an authoring checklist for adding new perf tests.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2154afbd-241a-431c-a79d-70ff6059da08

📥 Commits

Reviewing files that changed from the base of the PR and between 3275667 and 8923135.

📒 Files selected for processing (3)
  • packages/core/__perf__/README.md
  • packages/core/__perf__/compiler.perf.ts
  • packages/core/vitest.perf.config.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/core/perf/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/vitest.perf.config.ts
  • packages/core/perf/compiler.perf.ts

📝 Walkthrough

Walkthrough

Adds a perf benchmarking scaffold: root bench script and Vitest perf config, shared helpers for linear-chain specs and context, three calibrated perf tests (compileWorkflow 200-step, dag.resolve 1000-step, evaluate 10k iterations), and README documentation.

Changes

Performance Regression Testing Infrastructure

Layer / File(s) Summary
Test Configuration & CLI Setup
package.json, packages/core/vitest.perf.config.ts
Root bench script invokes Vitest with perf config; config limits discovery to __perf__/**/*.perf.ts, runs in forked workers for isolation, and sets 60-second timeout.
Perf Test Fixtures & Builders
packages/core/__perf__/_helpers.ts
makeLinearChainSpec(n) builds n-step linear workflows; makeLinearChainSteps(n) exposes steps; makeWorkflowContext() returns default context for stable measurements.
Calibrated Performance Tests
packages/core/__perf__/compiler.perf.ts, packages/core/__perf__/dag.perf.ts, packages/core/__perf__/expression.perf.ts
Three benchmark suites measure compileWorkflow scaling (200-step, 4500ms), dag.resolve (1000-step, 800ms), and evaluate throughput (10K iterations, 1000ms), each with warm-up run and timed assertion.
Perf Suite Documentation
packages/core/__perf__/README.md
Documents running benchmarks, three test coverage metrics, calibration methodology with headroom, and authoring checklist for new perf tests.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Poem

🐰 Hop, hop, the benchmarks run bright,

warm-ups tune and timers bite,
linear chains and ten-thousand tries,
thresholds watch where performance lies,
a rabbit cheers as regressions take flight. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description is comprehensive and covers the required template sections including summary, linked issue, spec impact checklist, and verification details. However, the PR has pending reviewer feedback on two technical issues that need resolution before merge. Address the two requested fixes: (1) standardize the ×1.5 multiplier across compiler.perf.ts and README.md (currently reference ×1.25), and (2) update vitest.perf.config.ts to use poolOptions.forks.singleFork: true for proper serialization.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding a performance benchmark scaffold with three calibrated assertions and an npm run bench command.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/__perf__/_helpers.ts`:
- Around line 47-50: The current makeLinearChainSteps uses an unsafe cast (as
Record<string, Step>) to silence that LogicSpec.steps is optional; replace this
by fixing the types instead of casting: either update the LogicSpec definition
(or the specific return type of makeLinearChainSpec) to make steps non-optional,
or if you must keep LogicSpec.steps optional, use a non-null assertion when
accessing spec.steps in makeLinearChainSteps (spec.steps!) so the compiler sees
you intended a present value; change the type in LogicSpec or the
makeLinearChainSpec return type to reflect that steps is always populated, or
use spec.steps! in makeLinearChainSteps and remove the as Record<string, Step>
cast.

In `@packages/core/__perf__/compiler.perf.ts`:
- Around line 13-17: Update the "Threshold calibration methodology" comment
block so it matches the actual calibration multiplier used (×1.5) instead of the
stale ×1.25; locate the header titled "Threshold calibration methodology" in
packages/core/__perf__/compiler.perf.ts and change the step describing "Multiply
by 1.25 (Math.ceil) for slower-machine headroom." to mention "Multiply by 1.5"
(and update any parenthetical/math note accordingly) so the top-of-file
methodology no longer contradicts the later documentation that documents ×1.5.

In `@packages/core/__perf__/README.md`:
- Line 62: The README contains a stale multiplier in the "Adding a new bench"
guide: replace the phrase "lock the worst × 1.25" with the correct multiplier
"lock the worst × 1.5" so it matches the calibration methodology described
earlier (the "calibration methodology" section that specifies ×1.5); update any
nearby explanatory text or examples that reference ×1.25 to use ×1.5 to keep the
guide consistent.

In `@packages/core/vitest.perf.config.ts`:
- Around line 11-21: The test pool currently sets pool: "forks" but doesn't
enforce single-fork serialization; update the Vitest config created by
defineConfig so that the test section includes poolOptions with forks.singleFork
set to true (i.e., add poolOptions: { forks: { singleFork: true } }) so all
"**/__perf__/**/*.perf.ts" tests run in one fork and avoid parallel CPU
contention; ensure you modify the object under test in the exported default
config where pool is set.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e8cc7d98-235d-4dbc-aee2-493e5c437bb9

📥 Commits

Reviewing files that changed from the base of the PR and between 83e1048 and ebdcd1a.

📒 Files selected for processing (7)
  • package.json
  • packages/core/__perf__/README.md
  • packages/core/__perf__/_helpers.ts
  • packages/core/__perf__/compiler.perf.ts
  • packages/core/__perf__/dag.perf.ts
  • packages/core/__perf__/expression.perf.ts
  • packages/core/vitest.perf.config.ts

Comment on lines +47 to +50
export function makeLinearChainSteps(n: number): Record<string, Step> {
const spec = makeLinearChainSpec(n);
return spec.steps as Record<string, Step>;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm the type of LogicSpec.steps in types.ts
rg -n "steps" --type ts -A 2 -B 2 packages/core/types.ts

Repository: SingularityAI-Dev/logic-md

Length of output: 1661


🏁 Script executed:

#!/bin/bash
# Find makeLinearChainSpec implementation
rg -n "makeLinearChainSpec" --type ts -A 10 packages/core/__perf__/_helpers.ts | head -40

Repository: SingularityAI-Dev/logic-md

Length of output: 969


Replace the as Record<string, Step> cast with a proper type fix.

The cast suppresses a real type mismatch: makeLinearChainSpec always populates steps, but TypeScript sees LogicSpec.steps as optional (Record<string, Step> | undefined). While the function logic guarantees steps are present, the type definition doesn't reflect this. Either make steps non-optional in LogicSpec (or in a dedicated return type from makeLinearChainSpec), or use a non-null assertion (spec.steps!) if the optional definition must remain. The silent cast hides a type safety gap.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/__perf__/_helpers.ts` around lines 47 - 50, The current
makeLinearChainSteps uses an unsafe cast (as Record<string, Step>) to silence
that LogicSpec.steps is optional; replace this by fixing the types instead of
casting: either update the LogicSpec definition (or the specific return type of
makeLinearChainSpec) to make steps non-optional, or if you must keep
LogicSpec.steps optional, use a non-null assertion when accessing spec.steps in
makeLinearChainSteps (spec.steps!) so the compiler sees you intended a present
value; change the type in LogicSpec or the makeLinearChainSpec return type to
reflect that steps is always populated, or use spec.steps! in
makeLinearChainSteps and remove the as Record<string, Step> cast.

Comment thread packages/core/__perf__/compiler.perf.ts Outdated
Comment thread packages/core/__perf__/README.md Outdated
Comment thread packages/core/vitest.perf.config.ts
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/core/vitest.perf.config.ts">

<violation number="1" location="packages/core/vitest.perf.config.ts:17">
P2: Benchmark config claims single-worker/serialized execution, but `pool: "forks"` alone does not prevent parallel workers, so perf timings can still be noisy.</violation>
</file>

<file name="packages/core/__perf__/README.md">

<violation number="1" location="packages/core/__perf__/README.md:62">
P3: The new-bench checklist conflicts with the calibration methodology: it says worst × 1.25 while the documented policy is worst × 1.5.</violation>
</file>

<file name="packages/core/__perf__/compiler.perf.ts">

<violation number="1" location="packages/core/__perf__/compiler.perf.ts:16">
P2: Stale methodology comment: line says "Multiply by 1.25" but the actual calibration used ×1.5 (as documented just below at line 23). This contradiction in the same header will mislead future recalibrators.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread packages/core/vitest.perf.config.ts
Comment thread packages/core/__perf__/compiler.perf.ts Outdated
Comment thread packages/core/__perf__/README.md Outdated
@SingleSourceStudios
Copy link
Copy Markdown
Collaborator

Solid execution. Two small things from the bot reviews worth addressing before merge:

  1. Multiplier inconsistency. compiler.perf.ts (lines 13-17) and perf/README.md (line 62) still say ×1.25; methodology block lower in the same files documents ×1.5. Picking ×1.5 across both is the right move. coderabbit and cubic both flagged it.

  2. Vitest pool config. pool: "forks" on its own does not actually serialize execution; poolOptions.forks.singleFork: true is what makes the comment claim ("One fork, serialised") match behaviour. Important for stable bench timings.

Address those and I'll merge. Otherwise the scaffold + 3 calibrated assertions are exactly the shape we discussed on #46.

antnewman added 2 commits May 8, 2026 16:14
…rtions

Refs SingularityAI-Dev#46.

Scaffolds the perf-assertion discipline as PR 1 of the four-PR sequence
agreed on the issue: scaffold first (this PR), then compiler fix,
expression cache, and DAG sort tightening as separate fixes that re-run
the bench to widen the margin.

What this adds:

- packages/core/__perf__/_helpers.ts — synthetic linear-chain spec
  generators
- packages/core/__perf__/compiler.perf.ts — compileWorkflow on a 200-step
  linear chain (threshold 1749ms)
- packages/core/__perf__/expression.perf.ts — evaluate × 10,000 calls on
  a varying context (threshold 479ms)
- packages/core/__perf__/dag.perf.ts — resolve on a 1000-step linear
  chain (threshold 269ms)
- packages/core/vitest.perf.config.ts — picks up only **/*.perf.ts,
  pool: forks for stable timings
- package.json — npm run bench wired

Threshold calibration follows the methodology agreed on SingularityAI-Dev#46: 5 runs on
main, take the worst, multiply by 1.25 for slower-machine headroom.
Calibration data is documented in the header of each *.perf.ts file so
recalibration after a fix is auditable. After PR 2 (compiler fix), the
compile assertion's margin should widen ~100x — that widening IS the
proof-of-fix signal, so the threshold should NOT be tightened in PR 2.

Linear chains are deliberately the worst-case shape (depth = node count).
compileWorkflow on a 200-step chain currently runs in ~1.3s on main
because every compileStep call re-resolves the full DAG (Candidate 1 in
SingularityAI-Dev#46). Pinning at 200 (rather than 1000) keeps total bench duration under
~5s; once the per-step DAG re-resolution is removed, the same workload
should drop to <50ms.

The bench is OPT-IN: default `npm test` does not run *.perf.ts. Only
`npm run bench` does. This avoids slowing the main test suite while
giving a clear pre-merge regression signal when needed.
…stability

Initial calibration (worst x1.25, single-machine) was too tight: re-runs
on a more loaded developer machine showed 2-3x variance on compileWorkflow
and ~2x on resolve, which pushed the assertions over their thresholds
even though no algorithmic regression had occurred.

Updated to use the worst observed across multiple sessions (quiet and
loaded) x1.5 for headroom. Verified stable across 3 consecutive runs.

The +50% trade-off (vs the +25% in the original SingularityAI-Dev#46 review) is justified
by the bench being opt-in (npm run bench, NOT default npm test) — stable
execution matters more than tight regression sensitivity. Once the
algorithmic fixes in PRs 2-4 land, the assertion margin widens
substantially (~100x for the compiler fix), so proof-of-fix remains
strong despite the wider initial headroom.

Each perf file's header comment documents both the quiet-run and
loaded-run timings so the trade-off is auditable.
antnewman added a commit to antnewman/logic-md that referenced this pull request May 8, 2026
…r consistency + Vitest 4 singleFork

Two small fixes per Rain's review on PR SingularityAI-Dev#53:

1. Multiplier consistency: compiler.perf.ts header methodology block and __perf__/README.md 'Adding a new bench' step both said x1.25; the calibration block in compiler.perf.ts (and README's main methodology section) had already moved to x1.5. Brought the inconsistent locations into line with x1.5 across the file. CodeRabbit and cubic-dev-ai both flagged this.

2. Vitest pool config: 'pool: forks' on its own does not actually serialise execution; in Vitest 4 the singleFork option moved from poolOptions.forks to a top-level forks block. Added 'forks: { singleFork: true }' so the comment claim ('One fork, serialised') matches behaviour.

Verified: bench runs 3x consecutively, all green; no Vitest deprecation warnings.
@antnewman antnewman force-pushed the perf/scaffold-with-baselines branch from ebdcd1a to 3275667 Compare May 8, 2026 16:37
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/core/vitest.perf.config.ts (1)

15-18: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use poolOptions.forks.singleFork instead of top-level forks (current shape is type-invalid).

Line 18 is causing the config type error and does not match the expected Vitest config object in this codebase. Move singleFork back under poolOptions.forks.

🔧 Proposed fix
 		// One fork, serialised, to minimise cross-test interference on timings.
-		// In Vitest 4, the `singleFork` option moved from `poolOptions.forks`
-		// to a top-level `forks` block — this is the new shape.
 		pool: "forks",
-		forks: { singleFork: true },
+		poolOptions: {
+			forks: { singleFork: true },
+		},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/vitest.perf.config.ts` around lines 15 - 18, The top-level
`forks: { singleFork: true }` is type-invalid; move `singleFork` back under
`poolOptions.forks` and remove the top-level `forks` block so the config uses
`pool: "forks"` with `poolOptions: { forks: { singleFork: true } }` (update the
object that currently contains `pool` and `forks` accordingly).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/core/vitest.perf.config.ts`:
- Around line 15-18: The top-level `forks: { singleFork: true }` is
type-invalid; move `singleFork` back under `poolOptions.forks` and remove the
top-level `forks` block so the config uses `pool: "forks"` with `poolOptions: {
forks: { singleFork: true } }` (update the object that currently contains `pool`
and `forks` accordingly).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3beb74d4-1bb9-4c41-bfb2-67ca9ad35b37

📥 Commits

Reviewing files that changed from the base of the PR and between ebdcd1a and 3275667.

📒 Files selected for processing (7)
  • package.json
  • packages/core/__perf__/README.md
  • packages/core/__perf__/_helpers.ts
  • packages/core/__perf__/compiler.perf.ts
  • packages/core/__perf__/dag.perf.ts
  • packages/core/__perf__/expression.perf.ts
  • packages/core/vitest.perf.config.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/core/perf/README.md
  • package.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/core/perf/dag.perf.ts
  • packages/core/perf/expression.perf.ts
  • packages/core/perf/_helpers.ts
  • packages/core/perf/compiler.perf.ts

…r consistency + Vitest 4 singleFork

Two small fixes per Rain's review on PR SingularityAI-Dev#53:

1. Multiplier consistency: compiler.perf.ts header methodology block and __perf__/README.md 'Adding a new bench' step both said x1.25; the calibration block in compiler.perf.ts (and README's main methodology section) had already moved to x1.5. Brought the inconsistent locations into line with x1.5 across the file. CodeRabbit and cubic-dev-ai both flagged this.

2. Vitest pool config: 'pool: forks' on its own does not actually serialise execution; in Vitest 4 the singleFork option moved from poolOptions.forks to a top-level forks block. Added 'forks: { singleFork: true }' so the comment claim ('One fork, serialised') matches behaviour.

Verified: bench runs 3x consecutively, all green; no Vitest deprecation warnings.
@antnewman antnewman force-pushed the perf/scaffold-with-baselines branch from 3275667 to 8923135 Compare May 8, 2026 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: missing scaling assertions on compiler, expression engine, and DAG resolver — three regression risks

2 participants