Skip to content

perf(test): round two — one shared release tarball per packed run, concurrent template scaffolds, narrow defineConfig stub - #82

Merged
ScriptedAlchemy merged 11 commits into
mainfrom
perf/test-suite-round-2
Aug 31, 2026
Merged

perf(test): round two — one shared release tarball per packed run, concurrent template scaffolds, narrow defineConfig stub#82
ScriptedAlchemy merged 11 commits into
mainfrom
perf/test-suite-round-2

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Aug 31, 2026

Copy link
Copy Markdown
Owner

What the "70-minute test run" actually was

Job compute is healthy; the wall clock is runner-queue time. In the 75-minute CI run on feat/prebuilt-payload-adapters (33390725959), every job finished in ≤11.5 min of compute, but Examples check and Verify (Node 26) sat queued for 64 minutes — each push starts 7 CI jobs plus a Package-preview job, and account-level runner concurrency saturates. Reducing total runner-minutes is the in-repo lever; this PR cuts the biggest consumers (3× Verify legs, release-gates) without touching coverage.

Fixes (each its own commit, behavior-preserving)

  1. One shared release tarball per test:packed run (13b0c470, 9b49dd7d) — the packed pool re-derived the same artifacts per test file: 7 full workspace builds (the pool never set AGENT_BUNDLE_PACKAGE_PREBUILT, several helpers ignored it, plus in-test pnpm builds) and ~10 npm packs + 2 copy-and-rebuild cycles. test:packed now builds once (NODE_ENV=production) and packs agent-bundle + create-agent-bundle once (scripts/run-packed-tests.mjs), sharing the tarballs through AGENT_BUNDLE_SHARED_PACK_DIR / tests/support/shared-pack.ts (lazy build-and-pack fallback for ad-hoc single-file runs). The stale-asset pruning test keeps its forced rebuild — that rebuild is the behavior under test.
  2. Concurrent template scaffolds (41858abc) — the three scaffolder e2e templates each own their project directory; running them via it.concurrent cuts the file from 37.5s to 15.4s (57s → 19s standalone).
  3. Narrow defineConfig stub in eval fixtures (744a65f8) — seedEvalProject's node_modules/agent-bundle shim re-exported defineConfig from src/index.ts; seeded configs load through Jiti with the module cache off, so every seeded project re-transpiled the whole package graph (~5s flat floor under each test). Re-exporting from src/core/types.ts (the defining module, same symbol — the existing project-fixture.ts pattern) removes the floor: eval-service.test.ts 206s → 11.8s, and eval-cli/evals-real/cli/agent-api/eval-workbench/dev-artifact-service inherit it.

Measured before/after (paired runs, same machine, alternating order; background load recorded — fixed runs generally ran under heavier load, so deltas are conservative)

Pool Baseline Fixed Delta
test:unit 1m23.1s 53.2s −36%
Integration, CI-serial shape (1 worker, prebuilt flags) 14m13.7s 9m01.9s −37%
test:packed (reporter-matched, build excluded) 3m53.9s 2m46.5s −29%
pnpm check end-to-end (fixed branch) 3m36s
pnpm check:release end-to-end (fixed branch) 3m41s

Biggest per-file integration wins (CI-serial shape): eval-service 206→11.8s, eval-cli 61→2.7s, evals-real 35.9→8.7s, cli 50.3→25.2s, agent-api 16.6→6.0s. Packed per-file: scaffold-packed 37.5→15.4s, release-audit 33.3→15.5s, public-api-packed 28.7→16.8s, dev-workbench-packaging 27.3→19.3s, rsc-runtime-optional 13.7→6.3s. Expected CI effect: each Verify leg's 12.8-min pnpm test drops ~4–5 min ×3 legs, easing the queue for every push.

Census proof (name-level)

  • Unit: 127 files, 1775 tests — 1771 passed / 4 skipped, identical before and after.
  • Integration (CI-serial): 51 files, 556 tests — 554 passed / 2 skipped, identical before and after.
  • Packed: 8 files, 23 tests — 22 passed / 1 skipped; automated name-level diff of all 23 tests: no additions, no removals, no status changes.

No changeset: nothing published changes (test/support/scripts layer only). Conflict zones respected: no edits to src/build/rslib.ts, build.test.ts, hooks.test.ts (PR #80) or packed-consumer.test.ts, overview.e2e.test.ts, runtime-playground.e2e.test.ts, examples/rsc-agent-runtime (PR #71).

Flagged for a future pass (not done here — this round cuts no coverage)

  • CI queue structure (the actual 70-minute cause): consider gating the Node 24/26 Verify legs to main pushes, and/or skipping Package preview on draft PRs — each push currently requests 8 runners.
  • overview.e2e.test.ts is now the dominant integration file (106s of the 540s serial pool) — natural round-three target, but PR feat: prebuilt payload adapter mode (RFC #50 Phase 3) #71 touches it today.
  • Packed pool file-level parallelization: blocked on dev-workbench-packaging's forced in-place dist rebuild racing release-audit's audit-script pack; restructuring would collide with PR refactor(build): serve generated entries through VirtualModulesPlugin at dedicated virtual paths #80's build-plugin rewrite.
  • npm install --prefer-offline in packed consumers (~2s × ~10 installs) — skipped to avoid touching install semantics in release-audit paths.
  • Prune candidates: none — no test looked provably redundant; the uniform eval floor was overhead, not coverage.

Adoption follow-ups (this PR was adopted after its authoring agent was aborted)

Merges from main: #71 and #80 merged during review; both are merged in and the full gate suite re-ran green on the merged head.

Simplify/deslop pass (f45dade4): one canonical installedEnvironment + npm-install flag list exported from tests/support/shared-pack.ts (five copies deleted; the workbench harness re-exports); the two run-level npm packs and packed-consumer's two disjoint installs run concurrently; dead packageRoot / packedServerStartupBudget leftovers and the harness's inline dynamic import removed; stale mobile-era locals in the packed-release desktop navigation walk renamed and a redundant viewport call dropped; public-api-packed's 15s budget joined its siblings at 30s (it wraps a real npm install plus a tsc run). packed-consumer.test.ts now documents why it deliberately bypasses the shared tarball: it packs from a deletable copy and deletes the pack source after install, proving the tarball holds no path references back to the pack root — a hermeticity property the shared (workspace-packed) tarball cannot test.

Packed-pool frequency policy (0bf2d54e)

Real npm work stays real, but each proof now has an owner:

  • Everyday loops (pnpm test / pnpm check): zero packed npm work, unchanged (the one remaining cycle is cli.test.ts's pack+install in the integration pool — flagged for round 3, entangled with that file's local helpers).
  • Per-PR CI (release gates → check:release:ci): the single-cycle consumer proofs (shared tarball: one build + two packs per run; one install per distinct consumer contract) plus one full scaffolder journey (minimal template: installed bin → scaffold → scaffolder-driven install → check → validate). Per-PR packed pool: 21 tests (20 passed / 1 skipped).
  • Release boundary (check:release pre-publish + nightly packed-matrix CI job): adds the scaffolder template matrix (scaffold-packed-matrix.e2e.test.ts: mcp-server, cli-tool). Full pool census is name-identical to the old per-PR pool: 23 tests (22 passed / 1 skipped).

What a template-matrix regression would now hit before the release gate: nothing per-PR beyond the minimal-template smoke — an mcp-server- or cli-tool-template-specific break (template manifest drift, stdio-entry wrapping, bin/lib/dts conventions inside a scaffolded project) surfaces at the nightly run or pre-publish check:release. The framework-side halves of those behaviors remain covered per-PR by packed-consumer.test.ts (framework-build project: bin/lib/dts + stdio lifecycle from the installed tarball) and the artifact validators.

Measured on the same machine (load ~45–60): old full pool on main 6m00s; new per-PR pool 3m02s; new release pool 3m05s (template matrix is concurrent, so its wall cost is small — the per-PR win is runner-minutes, npm work, and flake surface).

The packed pool re-derived the same release artifacts per test file: seven
full workspace `pnpm build`s (public-api-packed, release-audit x2,
dev-workbench-packaging, rsc-runtime-optional-packaging, packed-release.e2e
via the harness — the pool never set AGENT_BUNDLE_PACKAGE_PREBUILT) plus ten
`npm pack`s and two copy+rslib rebuilds in the scaffolder e2e.

`test:packed` now builds once, packs agent-bundle and create-agent-bundle
once (scripts/run-packed-tests.mjs), and hands the shared tarballs plus the
prebuilt seams to the pool through AGENT_BUNDLE_SHARED_PACK_DIR
(tests/support/shared-pack.ts, with a lazy build-and-pack fallback for
ad-hoc single-file runs). The stale-asset pruning test keeps its forced
rebuild — the rebuild is the behavior under test. Census is unchanged
(8 files, 22 passed / 1 skipped); the pool drops from 5m41s to 3m30s on the
same machine and no longer rebuilds the workspace at all.
Each template test scaffolds, installs, and checks its own project under
the shared runner, so nothing but the memoized pack fixture is shared.
Running them concurrently cuts the scaffolder e2e from ~57s to ~19s wall on
a development machine; the census is unchanged (same three tests).
seedEvalProject's node_modules/agent-bundle shim re-exported defineConfig
from src/index.ts — the whole package entry. Seeded configs load through
Jiti with the module cache off, so every project's config load re-transpiled
the entire package graph: a flat ~5s floor under each of the 35 eval-service
tests (3m9s for the file; the slowest file in the CI-serial integration leg
at ~150s) and under every other eval-project consumer.

Re-export from src/core/types.ts — defineConfig's defining module and the
exact symbol src/index.ts re-exports — the same way project-fixture.ts
already stubs it. eval-service drops from 3m9s to 15s locally with an
identical 35-test census; eval-cli, eval-workbench, agent-api,
dev-artifact-service, eval-native-mount, and evals-real inherit the same
floor removal.
…production

Review follow-ups from the shared-pack rework: the run-level build and both
npm pack invocations now run with NODE_ENV=production (matching the
production-build guarantee release-audit's in-test builds used to provide),
the build moved into scripts/run-packed-tests.mjs so `test:packed` has one
owner for the sequence, and the ad-hoc fallback in shared-pack.ts memoizes a
single process-wide build so concurrent callers (the scaffolder e2e requests
both packages at once) cannot race two workspace builds.
@changeset-bot

changeset-bot Bot commented Aug 31, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 8eb89b3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-31T16:16:57.573691Z 9b49dd7 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@pkg-pr-new

pkg-pr-new Bot commented Aug 31, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@82
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@82
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/rsc-runtime@82

commit: 5849b6a

…eftovers

Review follow-ups across the packed pool: one canonical installedEnvironment
and npm-install flag list exported from tests/support/shared-pack.ts (five
copies deleted; the workbench harness re-exports so its consumers are
untouched), the two run-level npm packs in scripts/run-packed-tests.mjs now
run concurrently, packed-consumer's two disjoint consumer installs run
concurrently and the test documents why it deliberately bypasses the shared
tarball (its deletable pack source proves the tarball holds no path
references back to the pack root), dead packageRoot/packedServerStartupBudget
leftovers and the harness's inline dynamic import are gone, the stale
mobile-era locals in the desktop navigation walk are renamed with the
redundant viewport call dropped, and public-api-packed's 15s budget joins its
siblings at 30s (it wraps a real npm install plus a tsc run).
Frequency policy for the packed pool: per-PR release gates keep the
single-cycle consumer proofs (pack once, install once per contract) plus one
full scaffolder journey — the minimal template, which covers the installed
scaffolder bin, template scaffold, scaffolder-driven npm install, project
check, and clean validate. The mcp-server and cli-tool template runs move to
scaffold-packed-matrix.e2e.test.ts, which runs in `test:packed:release`
(pre-publish check:release and a new nightly CI schedule), not per PR. The
shared scaffold fixture moves to tests/support/scaffold-fixture.ts; test
names are unchanged, so the release-boundary pool census is identical to the
old per-PR pool census, and the per-PR pool drops exactly the two matrix
templates. CI's release-gates job now runs check:release:ci (per-PR pool);
the nightly packed-matrix job runs the full check:release.
…o concurrent local-ci legs don't collide on /tmp
@ScriptedAlchemy
ScriptedAlchemy merged commit 39590cb into main Aug 31, 2026
8 of 9 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the perf/test-suite-round-2 branch August 31, 2026 22:16
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.

1 participant