You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Records the per-commit CI bottleneck analysis produced while rebasing codex/issue-360-warm-cache-levers onto origin/main (now 601460c, 2026-09-02), the rebase outcome itself, the decision on the one item that needed human judgment, and the post-merge measurements taken on 2026-09-08.
Evidence sources: docs/research/intra-pr-ci-cache.md (hosted timing measurements), docs/agents/ci.md, docs/desktop-release-operations.md, .github/workflows/ci.yml, .github/workflows/desktop-signed-preview.yml, the merged PRs #394, #405, #420, #422, #427, #428, #432, and the hosted runs linked below.
Verification run against the rebased tree: all six CI seam test files pass (101 tests: ci-affected-plan, ci-chapter-runner, ci-required-check, ci-verification-portfolio, ci-lbug-artifact, ci-runtime-artifact, plus desktop-release-main-ci-check); ci.yml YAML parses; JSON manifests and changed scripts pass syntax checks.
Decision (2026-09-08): keep #428's one-runner parallel Vitest, drop the shard (7e4ed3aa)
7e4ed3aa carried no hosted measurements. The first post-#428main run supplies them (33999200686, 2026-09-05):
Vitest job
vitest run wall
test/eval-app-integration.test.mjs
process-bound tail
125s
78s (176.6s of test CPU across the workers)
61s
~2s (the browser capture is skipped on CI)
The slow file already overlaps the rest of the isolated group on the one runner; it is the tail. A dedicated vitest-slow runner could bring the Vitest wall from ~78s to ~61s (the file's own duration) at ~40s of extra billed setup per run, and #420 found the shard silently broken on top of projects (CLI --exclude does not propagate into a project's resolved exclude). Decision: drop 7e4ed3aa. docs/agents/ci.md already documents the #428 arrangement, so no documentation change follows. The remaining Vitest headroom is inside the slow file (17 tests, 61s), not in runner topology.
Branch housekeeping: local codex/issue-360-warm-cache-levers (7e4ed3aa), backup/pre-rebase-2026-09-02 (e26c845), and backup/pre-rerebase (bd041af1) can be deleted; remote codex/issue-360-warm-cache-levers (306b25f) is merged as #420.
cargo build --release of the four workspace crates (dependencies fresh from the restored target/)
93s
electron-builder --dir + afterPack verification
~50s
The 93s is structural to the target-archive approach: on a fresh checkout Cargo's mtime fingerprints mark every path crate dirty, so the restored target/ only ever saves dependency compilation. Re-keying the archive would not help (as docs/agents/ci.md already notes). The lever with headroom is the #420 pattern applied to packaging: a digest-keyed, trusted-main-seeded bundle of the two aarch64-apple-darwin release binaries, verified through scripts/ci/runtime-artifact.mjs, installed into target/aarch64-apple-darwin/release/, with desktop:pack skipping the Ladybug/OpenSSL preparation and cargo when a verified bundle is installed and failing open to today's build otherwise. Expected: packaging ~4m35s → ~2m, after which the runtime lane → Vitest chain (~3m50s on Rust PRs, ~2m10s on non-Rust desktop PRs) is the critical path again. Plan pending approval.
4 Sep slow runs: an npm audit stall, not runner contention
Runs 33861852333 (10:09Z) and 33862873159 (10:21Z) took 9–11 minutes instead of ~5. Every job that runs npm ci lost 4–7 minutes in Set up Node dependencies (TypeScript builds 433s, Receipt integrity 430s, Quick 332s, Vitest 313s, packaging 323s); the Rust lanes, which do not run npm ci, were normal. In the slow jobs the ~/.npm cache was an exact hit (3s restore) and the runner image was identical to the fast runs (ubuntu-24.04 20260831.293.1). npm ci printed added 612 packages in 7m with no audited clause, where fast runs print added 631 packages, and audited 637 packages in 16s. npm status posted "npm audits endpoint is having issues" at 11:29Z that day; npm's fetch-timeout default is 300s with two retries, which matches a ~7-minute stall on the audit submission. #439's test-timeout changes address the symptom inside tests; the CI-side mitigation is npm ci --no-audit --no-fund in .github/actions/setup-node-dependencies (nothing in the repository consumes npm audit), which also trims a few seconds from every npm ci.
Cache budget
Repository cache stood at 8.61 GB of the 10 GB limit on 2026-09-08. Deleted 16 stale npm download caches (ten npm-* and six node-cache-* entries for superseded lockfile hashes, ~3.7 GB); usage is now 5.98 GB with only the two live npm-* entries for the current package-lock.json. PR-scoped sccache entries for merged PRs still hold ~2 GB and expire on GitHub's schedule.
PR release (candidate gate) = Desktop Signed Preview Candidates validate requires a completed successful full-portfolio ci.yml push run on main for the exact candidate commit.
(a) Runtime bundle missed structurally for narrow plans -> full runtime-lane build on every small PR; (b) slow Vitest file extends the Vitest wall; (c) under-covering bundle could store/install; empty-shard guard
Narrow plans structurally missed the seeded runtime bundle - "the exact small-change PRs the lever accelerates"
Same
-
7e4ed3aa rebased residual (dropped 2026-09-08)
Slow file test/eval-app-integration.test.mjs still ends the Vitest wall after #428's parallel config; a second runner would recover ~17s, see Decision above
-
-
Biggest bottlenecks per workflow today (post-merge, 2026-09-08)
PR workflow: (a) the packaging job's release rebuild plus Ladybug/OpenSSL preparation (~155s of a 275s job; the current critical path on main and on Rust PRs); (b) changed-unit Rust misses (~100-114 s per workspace crate; the Ladybug floor is gone); (c) the runtime lane -> Vitest chain (~97s + ~125s), which becomes critical once packaging drops; (d) fail-open full-mode selection for unmapped paths (by design, ~11-16 min); (e) npm ci exposure to registry-side stalls through the audit submission.
PR release (candidate gate): structural, not code - the candidate waits for the full-portfolio main CI run on the exact commit (fails closed; ~6 min warm after ci: warm the cache levers on top of the parallel Vitest portfolio #420, longer cold), and any flake reruns the whole gate on the release commit.
Summary
Records the per-commit CI bottleneck analysis produced while rebasing
codex/issue-360-warm-cache-leversontoorigin/main(now 601460c, 2026-09-02), the rebase outcome itself, the decision on the one item that needed human judgment, and the post-merge measurements taken on 2026-09-08.Evidence sources:
docs/research/intra-pr-ci-cache.md(hosted timing measurements),docs/agents/ci.md,docs/desktop-release-operations.md,.github/workflows/ci.yml,.github/workflows/desktop-signed-preview.yml, the merged PRs #394, #405, #420, #422, #427, #428, #432, and the hosted runs linked below.Rebase outcome
mainalready: Ladybug prebuilt bundle + crash-lane narrowing + precise mappings + flake fixes via Optimize CI: Rust timing artifacts, crash-lane affectedness, precise mappings, flake fixes #394; cache-lever warming, runtime-bundle portfolio-constant keying, and parallel Vitest config via ci: warm the cache levers on top of the parallel Vitest portfolio #420; nearby Seed the locked Cargo closure before the offline preview build #427/Gate desktop candidates on the main CI check, fold the crash lane, run Vitest in parallel #428.ci: shard Vitest across two runners with a dedicated slow job(11 files, +441/-38) directly onorigin/main(601460c). An earlier pass sat on 1dc9e50 as bd041af1; the re-rebase carried Stop wall-clock-bounded tests from reporting runner contention as failure #439's 15 s per-test-timeout note into the rewritten shard paragraph and kept Stop wall-clock-bounded tests from reporting runner contention as failure #439's 15 s timeout on the chapter-runner portfolio test.vitestshell with main'spackage.json(Gate desktop candidates on the main CI check, fold the crash lane, run Vitest in parallel #428 moved worker policy intovitest.config.js); the shard pins--maxWorkers=1in the chapter runner instead.ci-affected-plan,ci-chapter-runner,ci-required-check,ci-verification-portfolio,ci-lbug-artifact,ci-runtime-artifact, plusdesktop-release-main-ci-check);ci.ymlYAML parses; JSON manifests and changed scripts pass syntax checks.codex/issue-360-warm-cache-levers= 7e4ed3aa; pre-rebase history preserved atbackup/pre-rebase-2026-09-02(e26c845), intermediate rebase atbackup/pre-rerebase(bd041af1). Not pushed; the remote branch head (306b25f) was already merged as ci: warm the cache levers on top of the parallel Vitest portfolio #420.Decision (2026-09-08): keep #428's one-runner parallel Vitest, drop the shard (7e4ed3aa)
7e4ed3aa carried no hosted measurements. The first post-#428
mainrun supplies them (33999200686, 2026-09-05):vitest runwalltest/eval-app-integration.test.mjsThe slow file already overlaps the rest of the isolated group on the one runner; it is the tail. A dedicated
vitest-slowrunner could bring the Vitest wall from ~78s to ~61s (the file's own duration) at ~40s of extra billed setup per run, and #420 found the shard silently broken on top ofprojects(CLI--excludedoes not propagate into a project's resolved exclude). Decision: drop 7e4ed3aa.docs/agents/ci.mdalready documents the #428 arrangement, so no documentation change follows. The remaining Vitest headroom is inside the slow file (17 tests, 61s), not in runner topology.Branch housekeeping: local
codex/issue-360-warm-cache-levers(7e4ed3aa),backup/pre-rebase-2026-09-02(e26c845), andbackup/pre-rerebase(bd041af1) can be deleted; remotecodex/issue-360-warm-cache-levers(306b25f) is merged as #420.Post-merge measurements (2026-09-08)
The PR-workflow critical path is now packaging
checkstartsmain33999200686A non-Rust, non-desktop PR (runtime cache hit, packaging not selected) now finishes in ~1m25s (33999557594: plan 17s → Vitest 48s → check 9s).
Prime runtime package (macos-arm64)took 275s onmain: npm ci 24s, target-cache restore 16s,desktop:pack213s. Insidedesktop:pack:prepare:renderer+build:packagescargo build --releaseof the four workspace crates (dependencies fresh from the restoredtarget/)--dir+ afterPack verificationThe 93s is structural to the target-archive approach: on a fresh checkout Cargo's mtime fingerprints mark every path crate dirty, so the restored
target/only ever saves dependency compilation. Re-keying the archive would not help (asdocs/agents/ci.mdalready notes). The lever with headroom is the #420 pattern applied to packaging: a digest-keyed, trusted-main-seeded bundle of the twoaarch64-apple-darwinrelease binaries, verified throughscripts/ci/runtime-artifact.mjs, installed intotarget/aarch64-apple-darwin/release/, withdesktop:packskipping the Ladybug/OpenSSL preparation and cargo when a verified bundle is installed and failing open to today's build otherwise. Expected: packaging ~4m35s → ~2m, after which the runtime lane → Vitest chain (~3m50s on Rust PRs, ~2m10s on non-Rust desktop PRs) is the critical path again. Plan pending approval.4 Sep slow runs: an npm audit stall, not runner contention
Runs 33861852333 (10:09Z) and 33862873159 (10:21Z) took 9–11 minutes instead of ~5. Every job that runs
npm cilost 4–7 minutes inSet up Node dependencies(TypeScript builds 433s, Receipt integrity 430s, Quick 332s, Vitest 313s, packaging 323s); the Rust lanes, which do not runnpm ci, were normal. In the slow jobs the~/.npmcache was an exact hit (3s restore) and the runner image was identical to the fast runs (ubuntu-24.04 20260831.293.1).npm ciprintedadded 612 packages in 7mwith noauditedclause, where fast runs printadded 631 packages, and audited 637 packages in 16s. npm status posted "npm audits endpoint is having issues" at 11:29Z that day; npm'sfetch-timeoutdefault is 300s with two retries, which matches a ~7-minute stall on the audit submission. #439's test-timeout changes address the symptom inside tests; the CI-side mitigation isnpm ci --no-audit --no-fundin.github/actions/setup-node-dependencies(nothing in the repository consumesnpm audit), which also trims a few seconds from everynpm ci.Cache budget
Repository cache stood at 8.61 GB of the 10 GB limit on 2026-09-08. Deleted 16 stale npm download caches (ten
npm-*and sixnode-cache-*entries for superseded lockfile hashes, ~3.7 GB); usage is now 5.98 GB with only the two livenpm-*entries for the currentpackage-lock.json. PR-scoped sccache entries for merged PRs still hold ~2 GB and expire on GitHub's schedule.Workflow definitions used
ci.ymlonpull_request: planner -> chapters ->checkaggregate.Desktop Signed Preview Candidatesvalidate requires a completed successful full-portfolioci.ymlpush run onmainfor the exact candidate commit.desktop-signed-preview.yml: validate -> per-target signed/notarized package -> tagged Preview publication.Per-commit bottleneck mapping
test/eval-app-integration.test.mjsstill ends the Vitest wall after #428's parallel config; a second runner would recover ~17s, see Decision aboveBiggest bottlenecks per workflow today (post-merge, 2026-09-08)
mainand on Rust PRs); (b) changed-unit Rust misses (~100-114 s per workspace crate; the Ladybug floor is gone); (c) the runtime lane -> Vitest chain (~97s + ~125s), which becomes critical once packaging drops; (d) fail-open full-mode selection for unmapped paths (by design, ~11-16 min); (e)npm ciexposure to registry-side stalls through the audit submission.cargo fetch --lockednetwork fetch (mitigated by Seed the locked Cargo closure before the offline preview build #427's closure seeding); then the ~3m46s-4m18s package build plus external Apple signing/notarization latency; publication is gated on tag-annotation integrity (Restore the annotated tag object before reading its candidate pin #432), not time.Suggested next steps
npm ci --no-audit --no-fundin.github/actions/setup-node-dependencies.