Repository navigation
build: 7-day soak across toolchain and deps, cold-path hints, pinned tooling - #1020
Conversation
The pin is exact so the PGO/BOLT flow (mise run build:pgo, release upload-assets-pgo) instruments and optimizes with one toolchain and the collected profile matches the LLVM version that consumes it. llvm-tools-preview in components removes the manual 'rustup component add llvm-tools-preview' setup step. MSRV moves to 1.95 for core::hint::cold_path().
core::hint::cold_path() (stable since rust 1.95) annotates the rare arm so LLVM sinks it off the hot path. Sites: the per-file linker materialize loop's reflink/hardlink fallbacks and link-error return, the pnpm-lock byte-cursor subset parser's decline-to-serde bails, the thread-local semver range/version cache misses, and the per-entry tar walk's validation rejects. x86_64 Linux release binaries get PGO, but macOS/arm64/Windows ship plain release where static hints are the only branch-layout signal, and hints cover paths the hermetic PGO training run does not exercise.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe repository raises its Rust MSRV to 1.95, pins ChangesToolchain, supply-chain soak, and external tooling
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant CI
participant SoakManager
participant ExternalTools
participant SocketFirewall
participant PackageManager
CI->>SoakManager: Run --check
SoakManager->>SoakManager: Validate seven-day policy surfaces
CI->>ExternalTools: Install sfw with shims
ExternalTools->>SocketFirewall: Download and verify pinned binary
ExternalTools->>CI: Expose shim bin directory
CI->>PackageManager: Run dependency/install command
PackageManager->>SocketFirewall: Route command through sfw
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 @.rules:
- Line 6: Align the Buildkite PGO toolchain with the repository pin by updating
.buildkite/linux-agent.Dockerfile to use Rust 1.95.0 and install
llvm-tools-preview instead of bootstrapping stable or installing 1.93.0. Update
the corresponding toolchain references in .rules at lines 6 and 190 to
consistently specify the pinned 1.95.0 toolchain; both .rules sites require
direct updates.
🪄 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: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: 71b34b35-cb83-4587-80d7-1b022f0a9f51
📒 Files selected for processing (7)
.rulesCargo.tomlcrates/aube-linker/src/materialize.rscrates/aube-lockfile/src/pnpm/subset.rscrates/aube-resolver/src/semver_util.rscrates/aube-store/src/tarball.rsrust-toolchain.toml
Greptile SummaryThis PR introduces a 7-day "soak" supply-chain safety window across every dependency surface in the repo (cargo crates, npm packages, the pinned Rust nightly, renovate), plus
Confidence Score: 5/5Safe to merge — all changed paths are additive (new scripts, new config files, new cold-path hints) with no behavioural regressions in the install pipeline. The Rust changes are minimal and non-behavioural: cold_path() hints in error-only arms and a single refactor in source.rs that is semantically identical to the original. The soak system is pure additive infrastructure, covered by 47 unit tests that were expanded specifically to lock in every edge case caught during review. Previously flagged Windows .zip handling issues were addressed. The npm 12.0.0 soakBypass is correctly dated (removable 2026-07-16) and the CI gate will auto-enforce removal once that date passes. No files require special attention. scripts/soak/external-tools.mts has a pre-existing Windows .exe idempotency gap on the early-exit path that was flagged in a previous review cycle; it is tracked and does not affect POSIX CI. Important Files Changed
Reviews (22): Last reviewed commit: "fix(deps): close the renovate soak bypas..." | Re-trigger Greptile |
Adopt the newest nightly at least 7 days old as of 2026-07-11 and bump the pin under the same soak rule. rust-version stays 1.95 as the stable msrv floor. Verified on nightly-2026-07-04: clippy --all-targets -D warnings clean, fmt --check clean.
Crate versions published less than 7 days ago are pubtime-incompatible and the resolver skips them unless already in Cargo.lock. Unstable cargo feature, active via the nightly pinned in rust-toolchain.toml; stable cargo ignores the [unstable] table. Verified on nightly-2026-07-04: cargo update --dry-run holds back ~25 fresh versions vs a zero-age run and annotates the held ones (e.g. 'available: v0.1.8, published 3 days ago').
The agent image installed stable + 1.93.0 while rust-toolchain.toml now pins nightly-2026-07-04; pre-install the pinned toolchain (with llvm-tools-preview for PGO) and the 1.95 msrv floor so jobs don't rustup-download at job time.
scripts/soak/constants.mts is the ONE source for the release-age window; soak.mts parity-checks and fixes every surface (.cargo min-publish-age, docs/pnpm-workspace.yaml minimumReleaseAge in minutes, docs/.npmrc min-release-age in days, taze maturityPeriod via direct import). Version-pinned soak excludes require a '# published: | removable:' date annotation and expired pins are pruned by --fix. update-deps.mts bumps npm (taze) and cargo through the same window, refusing a non-rustup cargo that would silently skip the [unstable] soak. external-tools.json pins sfw/zizmor/agentshield/ skillspector exact with sha512 SRI; external-tools.mts is the only install path. taze lands through the docs/pnpm-workspace.yaml catalog: (kept in docs/ — a root workspace yaml would re-anchor the docs install), resolved by aube itself into aube-lock.yaml.
test-linux runs soak.mts --check and external-tools.mts --check, then installs sfw and its npm/yarn/pnpm/pip/uv/cargo shims. The SOCKET_SECURITY_KEY repo secret (not yet set) feeds SOCKET_API_KEY + SOCKET_API_TOKEN; until it lands sfw runs its keyless free tier, so the firewall is active either way and upgrades itself when the secret appears.
rustup --profile minimal with explicit components drops rust-docs (~600 MB per toolchain) from all three toolchains; rustup download caches are purged in-layer. Pre-bakes sfw-free 1.13.1 (sha512-pinned per arch, matching external-tools.json) plus the package-manager shims from a COPY'd template so agent jobs are firewalled without a per-job download.
paths.mts is the one declaration of every location the soak +
external-tools scripts touch (1 path, 1 reference); soak.mts,
update-deps.mts, and external-tools.mts import from it instead of
re-deriving. The tool rack moves to the repo-neutral
$XDG_DATA_HOME/aube/dev-tools/{rack,bin} (CI appends it via the new
--print-bin flag), the shim sentinel is SFW_SHIM_ACTIVE_*, and the
external-tools.json $schema pointer is dropped.
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
scripts/soak/paths.mts (1)
52-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse
EXTERNAL_TOOLS_JSONinstead of re-deriving the literal.Line 53 rebuilds
path.join(REPO_ROOT, 'external-tools.json'), which is exactlyEXTERNAL_TOOLS_JSON(Line 45). This duplicates the path literal that this module's own header (Lines 2-6) says should be declared exactly once.♻️ Proposed refactor
export function assertRepoRoot(): void { - if (!existsSync(path.join(REPO_ROOT, 'external-tools.json'))) { + if (!existsSync(EXTERNAL_TOOLS_JSON)) { throw new Error(`repo root not found at ${REPO_ROOT}`) } }🤖 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 `@scripts/soak/paths.mts` around lines 52 - 56, Update assertRepoRoot to pass the existing EXTERNAL_TOOLS_JSON constant to existsSync instead of rebuilding the path with REPO_ROOT and the 'external-tools.json' literal. Leave the error behavior unchanged.
🤖 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 @.buildkite/linux-agent.Dockerfile:
- Around line 34-58: Keep the sfw-free version, architecture-specific assets,
and SHA512 values in sync with external-tools.json by adding a build-time
validation step around the sfw-free installation in the Dockerfile. Have it
parse the manifest’s corresponding 1.13.1 pin and checksums, compare them with
the values used by the asset selection and sha512sum verification, and fail on
any mismatch; avoid maintaining an independently editable duplicate.
In `@docs/taze.config.mts`:
- Around line 8-14: Update the dry-run argument selection in update-deps so dry
runs explicitly pass --no-write and cannot modify package.json, while preserving
--write for normal runs; ensure this override is consistent with the write
setting in docs/taze.config.mts.
In `@scripts/soak/external-tools.mts`:
- Around line 110-125: Update the fetch call in download to include signal:
AbortSignal.timeout(30_000), preserving the existing headers and redirect
options so stalled downloads fail after 30 seconds.
In `@scripts/soak/update-deps.mts`:
- Around line 67-74: Update the status handling in the function containing the
onlyCargo and onlyNpm branches so updateNpm(dryRun) and updateCargo(dryRun) are
both invoked whenever their ecosystems are enabled, regardless of the other
result. Aggregate each returned status after execution while preserving the
existing flag behavior and final status return.
---
Nitpick comments:
In `@scripts/soak/paths.mts`:
- Around line 52-56: Update assertRepoRoot to pass the existing
EXTERNAL_TOOLS_JSON constant to existsSync instead of rebuilding the path with
REPO_ROOT and the 'external-tools.json' literal. Leave the error behavior
unchanged.
🪄 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: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: f3f961f9-1b63-4bbe-a139-c2f5fa29d0f3
📒 Files selected for processing (17)
.buildkite/linux-agent.Dockerfile.buildkite/sfw-shim-template.sh.github/workflows/ci.yml.rulesdocs/.gitignoredocs/.npmrcdocs/aube-lock.yamldocs/package.jsondocs/pnpm-workspace.yamldocs/taze.config.mtsexternal-tools.jsonmise.tomlscripts/soak/constants.mtsscripts/soak/external-tools.mtsscripts/soak/paths.mtsscripts/soak/soak.mtsscripts/soak/update-deps.mts
💤 Files with no reviewable changes (1)
- docs/.gitignore
✅ Files skipped from review due to trivial changes (3)
- docs/.npmrc
- docs/pnpm-workspace.yaml
- .rules
When a package.json next to the workspace yaml pins a cataloged package to an exact version instead of catalog: (npm-cli compat), soak.mts now fails check unless the two versions match. catalog: references no-op.
The taze config sets write: true, so a dry run must pass --no-write explicitly or it rewrites package.json; also suppress the ni install prompt with --no-install.
A hung release or registry response would stall CI indefinitely; abort after 120s (generous for the largest pinned binary on a slow runner).
- reject flow-style minimumReleaseAgeExclude (invisible to the block parser = unvalidated bypass) and parse entries with trailing comments; catalog parity tolerates blank lines in the block - entrypoint guard uses realpath + pathToFileURL so symlinked or space-containing checkouts don't silently no-op the gate - linkHandle force-removes dangling handles (EEXIST wedge) - extract .zip release assets via bsdtar and verify the binary landed - GITHUB_TOKEN only sent to github.com, never the npm registry - npm-purl installs key completion off the extracted manifest so an interrupted extract self-heals - update-deps runs every requested ecosystem and reports spawn errors - sfw install/shims skip cleanly on windows (POSIX-only mechanism) - Socket credential is SOCKET_SECURITY_KEY everywhere — no SOCKET_API_* aliasing in CI env or the enterprise-tier check - buildkite image verifies the mise install instead of trusting an unchecked curl|sh
The buildkite image build context is .buildkite/ alone, so its embedded sfw pin (version + per-arch sha512 hex) and toolchain channels can't derive from external-tools.json / rust-toolchain.toml directly; external-tools.mts --check now hex-decodes the SRI pins and fails on any drift between the Dockerfile copies and the tracked sources (same parity idiom as the soak data files). Adds untracked 1.6.4 through the docs catalog for ignore-file generation on docker-context builds.
pnpm 11.8.0 (per-platform SRI assets) and npm 12.0.0 (single registry tarball, soakBypass-annotated — inside the 7-day window by deliberate dated exception) join external-tools.json; CI installs both before the firewall shims, and the shims wrap the PINNED binaries directly (rack target embedded at shim-write time) instead of whatever PATH finds. External npm-packaged tools now materialize their runtime deps through the repo's own package manager first (aube, then pnpm/npm fallbacks) — installs are script-skipping and prod-only. CI asserts pnpm/npm resolve through the shims after install.
…unit tests writeShims wrote THROUGH the rack symlink handle, overwriting the pinned binary with the shim body — which then exec'd itself forever (the mysterious local hang). Remove the handle before writing. Windows .zip archives resolve <bin>.exe before failing, and a failed extract cleans its dir so retries re-extract. Annotation and soakBypass dates must be real calendar dates (finding, not a RangeError crash), and an expired soakBypass is now flagged like any other soaked pin. 23 node:test unit tests cover the checkers, fixers, and parsers (mise run test:scripts; also in the CI gate).
…ates widened - drop uncalled assertRepoRoot and the never-false 'required' surface knob; inline the single-use hasSocketToken wrapper (own forbidden rule); shared extractArchive replaces two near-duplicate tar blocks; installNpmTarball parses the manifest once - writeShims resolves rack pins from the manifest + rack contents instead of the bin handle, making a --shims re-run keep the pinned target (idempotence regression covered by tests) - new tmpdir-isolated rack tests (XDG_DATA_HOME sandbox): the symlink-clobber and dangling-handle regressions, rackRealFor resolution, shim idempotence; dockerignore surface tests (skip here — no repo-context docker builds) - docker prebake gate also asserts the shim ecosystem list and the msrv toolchain; test fixtures derive from SOAK_DAYS instead of hand-copying 7; CI gate defers to the mise tasks; number-carrying comments next to managed values are now number-free; prose names SOCKET_SECURITY_KEY (the env var the code reads)
The toolchain rule was prose; now rust-toolchain.toml carries a machine-read '# adopted: YYYY-MM-DD' line and soak.mts enforces adopted >= nightly date + SOAK_DAYS as a fifth checked surface (stable pins pass freely; missing/impossible dates are findings). .claude/skills/soak/SKILL.md documents the whole system pointing at scripts/soak/: the one-place window change (edit SOAK_DAYS, run soak:fix), the committed-only opt-out (SOAK_DAYS = 0 — deliberately no env bypass), per-package dated excludes, per-tool soakBypass, and the nightly bump procedure. .gitignore opens /.claude/skills/ for tracking (contents-exclusion + negation, since git cannot re-include children of an excluded directory).
|
This PR currently has failing checks. If this continues for 7 days, it will be closed automatically. This is warning day 1 of 7. Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it. This comment was generated by an automated workflow. |
- tar on Windows parses an absolute C:\ archive path as a remote
host:path ("Cannot connect to C") — extract with a cwd-relative
archive name instead
- the buildkite shim template's if-body used spaces where the repo's
shfmt profile mandates tabs (surfaced once clippy stopped failing
first)
…siblings pnpm's Windows SEA launcher resolves dist/pnpm.mjs relative to the invoked handle's directory, so a symlinked/copied bin handle crashes with MODULE_NOT_FOUND. On win32 the handle is now a forwarding pair (.cmd for cmd/pwsh + extensionless bash shim for Git Bash) that invokes the absolute rack target; registry-tarball tools forward through node directly instead of a bash-only wrapper pwsh can't run.
…ubepkg#1020, aubepkg#1039) Re-lands the 7-day dependency soak window and the pinned-tooling setup, guarded so it can't push the MSRV ceiling. Folds in the follow-up review and adversarial-review fixes made on top of the original re-land: loud failures when cargo silently ignores min-publish-age, npm min-release-age-exclude gating, unauthenticated download fallback with a single 5xx retry, scoping the firewall past the cargo suite, and the soak-fixer no longer reformatting files it does not own.
What this PR does
This PR gives aube one supply-chain safety rule — a 7-day "soak" — and applies it everywhere a dependency or tool can enter the repo. The idea: when a new version of anything is published, we wait 7 days before adopting it. If that version turns out to be compromised (like the recent npm supply-chain attacks), the ecosystem usually finds out within days — and we never installed it.
It also adds
core::hint::cold_path()branch hints to aube's hottest install loops (the perf work that kicked this off), pins every external tool we use by exact version + checksum, and routes CI installs through Socket Firewall.The soak, explained (start here)
"Soak time" = the minimum age a release must reach before we install it. Ours is 7 days, defined once in
scripts/soak/constants.mts(SOAK_DAYS = 7). Every other file derives from or is checked against that one constant, so the number can't quietly drift between config files:rust-toolchain.toml.cargo/config.toml-Zmin-publish-ageskips crate versions younger than 7 daysdocs/pnpm-workspace.yamlminimumReleaseAge: 10080— same rule in minutes, read by aube itselfdocs/.npmrcmin-release-age=7for anyone using npm ≥ 11.17 directlydocs/taze.config.mts.github/renovate.jsonminimumReleaseAge: "7 days", explicit in-repo (the shared preset already sets it, but preset drift would be silent) — Renovate commits updated lockfiles, and-Zmin-publish-ageskips already-locked versions, so Renovate itself is the only place this path can be soakedFun part: aube ships
minimumReleaseAgeas a feature for its users — this PR makes aube's own repo use it (the docs deps install with aube itself).The soak manager:
scripts/soak/constants.mts— the one source of truth (SOAK_DAYS, plus the annotation rules below).paths.mts— every file path the scripts touch, declared exactly once ("1 path, 1 reference"). This is the only file that differs from nub's copy of these scripts.soak.mts --check— fails CI if any surface drifts fromSOAK_DAYS.--fixrewrites them.update-deps.mts— bumps npm deps (via taze) and cargo deps, both under the soak. It refuses to runcargo updatewith a non-rustup cargo, because only rustup's cargo readsrust-toolchain.toml— a Homebrew cargo would silently skip the soak.external-tools.mts— installs the pinned external tools (below)..claude/skills/soak/SKILL.md— a repo skill so agent sessions pick up the procedures (change the window, opt out, add an exclusion, bump the nightly) without re-deriving them. Written to Anthropic's skill-authoring + prompting guidance, which it links; the skill documents the law,scripts/soak/is the law.Skipping the soak for one package is allowed but must be visible and temporary. A version-pinned entry in
minimumReleaseAgeExcluderequires a dated comment right above it:removablemust equalpublished + 7 days. Once that date passes, the pin has soaked and--checkfails until it's removed (--fixprunes it). Unannotated pins, impossible dates (2026-13-45), and flow-style[...]lists (which the parser can't validate) are all rejected.Pinned external tools + Socket Firewall in CI
external-tools.jsonpins every external tool to an exact version with a sha512 SRI (a checksum: if the downloaded bytes don't hash to the pinned value, the install fails). Pinned: pnpm 11.8.0, npm 12.0.0, sfw (Socket Firewall, free + enterprise tiers), zizmor, agentshield, skillspector.external-tools.mts --install <name>downloads, verifies the checksum, and installs into a local "rack" ($XDG_DATA_HOME/aube/dev-tools/rack/<tool>/<version>/) with a symlink in abin/dir you put on PATH. npm-packaged tools get their own deps installed by aube itself (dogfooding), prod-only with lifecycle scripts skipped.--shimswrites tiny bash wrappers namednpm,pnpm,cargo, etc. that route the real command throughsfw— so every package install in CI passes through the firewall. When the command itself is one of our pinned PMs, the shim executes the pinned binary, not whatever PATH happens to find.About the secret:
SOCKET_SECURITY_KEYis the only credential env var. It isn't set in this repo yet — that's fine, because sfw's free tier needs no key. When the secret lands, the same code automatically selects the enterprise tier.One thing that deliberately does NOT auto-update: npm 12.0.0 is younger than 7 days, so its pin carries a
soakBypassannotation with the same published/removable dates — and--checkfails once that window passes without the annotation being removed.Buildkite image: smaller and pin-checked
The CI agent image now installs its three Rust toolchains with
--profile minimal(the default profile ships rust-docs — roughly 600 MB per toolchain we never read in CI), and pre-bakes sfw + its shims so jobs don't download them every run.The catch: the image builds from
.buildkite/alone, so its Dockerfile cannot readexternal-tools.jsonorrust-toolchain.toml— it has to embed copies of the version + checksums. Copies drift. Soexternal-tools.mts --check(run in CI) decodes the checksums and fails if the Dockerfile's copies stop matching the tracked pins. Same trick the soak uses for.npmrc: when a file can't import the constant, a check asserts it matches.The cold-path hints (the original perf work)
core::hint::cold_path()(stable since Rust 1.95 — hence the MSRV bump 1.93 → 1.95) tells the optimizer "this branch almost never runs", so it moves that code out of the hot instruction stream. Applied to the rare arms of four hot loops: the per-file linker materialize loop (reflink→hardlink→copy fallbacks), the pnpm-lockfile byte parser's bail-out paths, the semver cache misses, and the tar-extraction validation errors.Why bother when we have PGO? Only x86_64 Linux release builds get PGO+BOLT — macOS, arm64, and Windows ship plain builds where these hints are the only branch-layout signal. The toolchain itself is pinned to
nightly-2026-07-04(the newest nightly ≥ 7 days old when adopted; nightly is required for-Zmin-publish-age), whilerust-version = "1.95"stays the declared stable floor.How it's tested
node:testunit tests cover the checkers, fixers, parsers, and CLIs (mise run test:scripts; also part of the CI gate) — ~82% line coverage overall. Review findings live on as regression cases (impossible calendar dates, expired bypasses, flow-style lists, trailing comments, catalog drift, the--npm --cargoselector bug), and the security-relevant paths are pinned by tests: the downloader sendsGITHUB_TOKENto github.com only and rejects any checksum mismatch, the sfw flavor flips onSOCKET_SECURITY_KEY, every Dockerfile-prebake drift class fires against a synthetic image, and both CLIs round-trip end-to-end through their entrypoints.-D warnings+ fmt clean on the pinned nightly; cargo unit tests green (6 pre-existing registry-mock failures on the dev machine come from a local TLS proxy, not this PR).cargo update --dry-runholds back ~25 too-fresh versions with "published N days ago" notes; taze only proposes soaked versions.11.8.0/12.0.0), and CI asserts that on every run.This PR was generated by Claude.
Post-open additions
.cmd+ bash shims (a copied handle strands pnpm's SEA launcher from itsdist/siblings), extraction uses System32 bsdtar cwd-relative, and the handle base strips.exeso pwsh never tries to execute a bash forwarder as a PE binary.soak.mtsnow parity-checks.github/renovate.jsonminimumReleaseAgeagainstSOAK_DAYS(with--fix), closing the one dependency path the local surfaces can't gate.scripts/soak/remotes.mtsdeclares where PRs live vs where branches push (--check/--fix/--print+mise run remotes:check), so tooling reads it instead of rediscovering it.