Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
254a9c4
build: pin rust 1.95.0 toolchain and bump msrv to 1.95
jdalton Jul 11, 2026
c99106d
perf: mark rare branches in hot install loops with cold_path()
jdalton Jul 11, 2026
c27c5fe
build: switch toolchain pin to nightly-2026-07-04 (7-day soak)
jdalton Jul 11, 2026
297e659
build: enable cargo min-publish-age with a 7-day soak
jdalton Jul 11, 2026
8e4684d
ci: pre-bake pinned nightly and 1.95 msrv floor in buildkite image
jdalton Jul 11, 2026
5a228bc
build: add 7-day soak manager, taze via catalog, pinned external tools
jdalton Jul 11, 2026
1d06f6a
ci: gate soak + tool pins and route installs through socket firewall
jdalton Jul 11, 2026
b813143
ci: shrink buildkite image via minimal toolchains, prebake sfw shims
jdalton Jul 11, 2026
19abecd
refactor(soak): single paths.mts reference, neutral tool-rack layout
jdalton Jul 11, 2026
5cd4f68
feat(soak): enforce catalog-shadowed pin lockstep
jdalton Jul 11, 2026
aa2f172
fix(soak): make update-deps dry-run actually dry
jdalton Jul 11, 2026
7a593b5
fix(soak): timeout stalled external-tool downloads
jdalton Jul 11, 2026
f2c6590
fix(soak): harden gates and installer against review findings
jdalton Jul 11, 2026
269bfab
build: gate docker prebake pins against tracked sources, add untracked
jdalton Jul 11, 2026
e16c379
build: pin pnpm 11.8 + npm 12 via the tool rack, dogfood dep installs
jdalton Jul 11, 2026
0676cf0
fix(soak): shim self-clobber, windows .exe resolve, date guards; add …
jdalton Jul 11, 2026
9166cfd
refactor(soak): perfectionist pass — dead code out, tests isolated, g…
jdalton Jul 11, 2026
1caeae6
feat(soak): enforce the toolchain nightly soak, add the soak skill
jdalton Jul 11, 2026
3c1e24e
docs(soak): align skill with claude prompting and skill-authoring gui…
jdalton Jul 11, 2026
cb6edd6
test(soak): cover cli paths, fixers, download token gating, installer…
jdalton Jul 11, 2026
eb89281
refactor(soak): dedupe the rust-toolchain.toml path, complete the hea…
jdalton Jul 11, 2026
d7d95f3
ci: bypass sfw for cargo — the proxy breaks local registry-mock tests
jdalton Jul 11, 2026
4d99f93
style(lockfile): satisfy nightly clippy question_mark in local source…
jdalton Jul 12, 2026
806bc95
fix(soak): windows-safe relative tar extraction; shfmt the shim template
jdalton Jul 12, 2026
d23f610
fix(soak): use System32 bsdtar on windows — Git Bash's GNU tar can't …
jdalton Jul 12, 2026
699d0a0
fix(soak): windows handles forward to the rack — symlinks strand SEA …
jdalton Jul 12, 2026
8be5a02
fix(deps): strip .exe from win32 tool handle base name
jdalton Jul 12, 2026
7117e19
chore: encode PR home + push fork as a checked remote map
jdalton Jul 12, 2026
d7cf256
fix(deps): close the renovate soak bypass — explicit minimumReleaseAg…
jdalton Jul 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions .buildkite/linux-agent.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,51 @@ RUN apt-get update \
xz-utils \
&& rm -rf /var/lib/apt/lists/*

RUN curl https://mise.run | sh
# -f + explicit installer file: a piped `curl | sh` with no -f would let a
# network-level curl failure produce an empty script and a silently
# mise-less image; verifying the binary afterwards fails the layer loudly.
RUN set -eux; \
curl --proto '=https' --tlsv1.2 -fsSL https://mise.run -o /tmp/mise-install.sh; \
sh /tmp/mise-install.sh; \
rm /tmp/mise-install.sh; \
/root/.local/bin/mise --version
# Pre-bake the repo's toolchains with MINIMAL profiles + only the components
# jobs use (the default profile ships rust-docs, ~600 MB per toolchain):
# - nightly-2026-07-04: the rust-toolchain.toml pin (rustfmt/clippy for
# lint jobs, llvm-tools-preview for the PGO flow)
# - 1.95.0: the msrv floor cargo-msrv verifies against
# - stable: rustup's default for anything outside the repo checkout
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --profile default --default-toolchain stable \
&& /root/.cargo/bin/rustup toolchain install 1.93.0 --profile default \
&& /root/.cargo/bin/rustup component add rustfmt clippy --toolchain stable
| sh -s -- -y --profile minimal --default-toolchain stable \
&& /root/.cargo/bin/rustup toolchain install nightly-2026-07-04 --profile minimal \
-c rustfmt -c clippy -c llvm-tools-preview \
&& /root/.cargo/bin/rustup toolchain install 1.95.0 --profile minimal \
&& rm -rf /root/.rustup/downloads /root/.rustup/tmp

ENV PATH="/root/.cargo/bin:/root/.local/bin:/root/.local/share/mise/shims:${PATH}"
# Pre-bake Socket Firewall (free tier — keyless; jobs holding a Socket key
# select enterprise at job time) plus its package-manager shims, pinned +
# integrity-checked against external-tools.json (sfw-free 1.13.1, sha512
# hex below = that file's SRI decoded).
COPY sfw-shim-template.sh /tmp/sfw-shim-template.sh
RUN set -eux; \
arch="$(uname -m)"; \
case "$arch" in \
x86_64) asset=sfw-free-linux-x86_64; sha=c1a2ebb0f1b66bb10ebf45eebd70d0646802678313b4e7d987c4e619b33a827d81e8d87a1c8fb5e636a829d012f7081d4f222a4eea94f8ef8db5561dfa4b8568 ;; \
aarch64) asset=sfw-free-linux-arm64; sha=158458479d922fe28a165756e288183949d31f9392aafb57c331857968b45b6c7eef929970f886cd605b84c9a1d1fe50b6060b57ee2a75112098a08111ac8db4 ;; \
*) echo "unsupported arch $arch" >&2; exit 1 ;; \
esac; \
mkdir -p /root/.local/share/aube/dev-tools/rack/sfw-free/1.13.1 /root/.local/share/aube/dev-tools/bin; \
curl -fsSL -o /root/.local/share/aube/dev-tools/rack/sfw-free/1.13.1/sfw \
"https://github.com/SocketDev/sfw-free/releases/download/v1.13.1/$asset"; \
echo "$sha /root/.local/share/aube/dev-tools/rack/sfw-free/1.13.1/sfw" | sha512sum -c -; \
chmod 0755 /root/.local/share/aube/dev-tools/rack/sfw-free/1.13.1/sfw; \
ln -sf /root/.local/share/aube/dev-tools/rack/sfw-free/1.13.1/sfw /root/.local/share/aube/dev-tools/bin/sfw; \
for cmd in npm yarn pnpm pip pip3 uv cargo; do \
sentinel="SFW_SHIM_ACTIVE_$(printf '%s' "$cmd" | tr '[:lower:]' '[:upper:]' | tr -c 'A-Z0-9' '_')"; \
sed -e "s/__CMD__/$cmd/g" -e "s/__SENTINEL__/$sentinel/g" \
/tmp/sfw-shim-template.sh > "/root/.local/share/aube/dev-tools/bin/$cmd"; \
chmod 0755 "/root/.local/share/aube/dev-tools/bin/$cmd"; \
done; \
rm /tmp/sfw-shim-template.sh
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

ENV PATH="/root/.local/share/aube/dev-tools/bin:/root/.cargo/bin:/root/.local/bin:/root/.local/share/mise/shims:${PATH}"
16 changes: 16 additions & 0 deletions .buildkite/sfw-shim-template.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
# sfw shim for __CMD__ — pre-baked into the agent image; mirrors what
# scripts/soak/external-tools.mts --shims writes on dev machines. Routes the
# real package-manager invocation through Socket Firewall; the sentinel env
# var breaks recursion when sfw re-invokes the tool, and the real binary is
# found by stripping the tool-rack bin dir out of PATH.
set -euo pipefail
CLEAN_PATH=$(printf '%s' "$PATH" | tr ':' '\n' | grep -vFx '/root/.local/share/aube/dev-tools/bin' | paste -sd ':' -)
REAL=$(PATH="$CLEAN_PATH" command -v '__CMD__' || true)
if [ -n "${__SENTINEL__:-}" ] || [ -z "$REAL" ] || ! command -v sfw >/dev/null 2>&1; then
[ -n "$REAL" ] && exec "$REAL" "$@"
echo "__CMD__: not found" >&2
exit 127
fi
export __SENTINEL__=1
exec sfw '__CMD__' "$@"
12 changes: 12 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,15 @@
# (7.07 s → 9.57 s) — acceptable given the safety guarantee.
[env]
RUST_TEST_THREADS = "1"

# Supply-chain soak for cargo's own dependency resolution — the same
# soak-window rule aube offers npm users via minimumReleaseAge: crate
# versions younger than the window are pubtime-incompatible and the
# resolver skips them unless already in Cargo.lock
# (resolver.incompatible-publish-age defaults to "deny"). The unstable
# feature is active because rust-toolchain.toml pins a nightly.
[unstable]
min-publish-age = true

[registry]
global-min-publish-age = "7 days"
89 changes: 89 additions & 0 deletions .claude/skills/soak/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
name: soak
description: Manages the repo's supply-chain soak window (SOAK_DAYS) — checks and fixes the derived surfaces, bumps or disables the window, adds dated per-package exclusions, and bumps pinned external tools. Use when a task touches minimumReleaseAge, min-release-age, min-publish-age, the nightly toolchain pin, external-tools.json, renovate.json, or taze cooldowns, or when investigating why a freshly published version won't install.
---

# The soak window

One rule: a release must be at least `SOAK_DAYS` old before this repo
adopts it. The delay gives the ecosystem time to catch a malicious or
yanked release before we ever install it. The window is defined exactly
once — read the current value from `scripts/soak/constants.mts` and never
hardcode it elsewhere. Every surface derives from or is parity-checked
against it:

| Surface | Key | Units |
|---|---|---|
| `.cargo/config.toml` | `global-min-publish-age` | `"N days"` |
| `rust-toolchain.toml` | nightly channel date vs `# adopted:` line | days |
| `docs/pnpm-workspace.yaml` | `minimumReleaseAge` | minutes |
| `docs/.npmrc` | `min-release-age` | days |
| `docs/taze.config.mts` | `maturityPeriod` | imports `SOAK_DAYS` |
| `external-tools.json` | `soakBypass` annotations | days |
| `.github/renovate.json` | `minimumReleaseAge` (explicit — an `extends:` preset doesn't count) | `"N days"` |

## Commands (mise tasks — the scripts live in `scripts/soak/`)

- `mise run soak` — parity-check every surface (CI-gated in test-linux)
- `mise run soak:fix` — rewrite drifted windows, prune expired exclusions
- `mise run deps:update` — bump npm (taze) + cargo deps through the window
- `mise run tools:check` / `tools:install` — validate / install the
SRI-pinned external tools (`external-tools.json`)
- `mise run test:scripts` — the scripts' own unit tests

A soak change is done when `mise run soak` and `mise run test:scripts`
both exit 0 — the same gates CI runs. Re-run them after every fix.

## Change the window (one place)

1. Edit `SOAK_DAYS` in `scripts/soak/constants.mts`.
2. `mise run soak:fix` (rewrites cargo/npmrc/yaml; taze follows by import).
3. `mise run soak` + `mise run test:scripts` — existing exclusion
annotations encode the old window and will be flagged; re-date or
remove them, then re-run until both pass.

**Opt out entirely**: set `SOAK_DAYS = 0` and run the same two steps —
cargo, pnpm/aube (`minimumReleaseAge: 0`), npm, and taze all treat zero as
disabled. There is deliberately no env-var bypass: opting out is a
committed, reviewable change, never a silent one.

## Skip the soak for ONE package (dated, temporary)

Add to `minimumReleaseAgeExclude` in `docs/pnpm-workspace.yaml` with the
annotation on the line above (block list only — flow `[..]` is rejected
because a comment line can't attach to an inline entry):

```yaml
# published: 2026-07-08 | removable: 2026-07-15
- 'name@1.2.3'
```

`removable` = `published + SOAK_DAYS` (this example assumes a 7-day
window). `published` must be the real registry publish date. Once
`removable` passes, `mise run soak` fails until the pin is pruned
(`soak:fix` does it). Bare names / `@scope/*` globs are standing trust and
need no annotation. External tools use the same shape via a `soakBypass`
object in `external-tools.json`.

## Bump the nightly toolchain

Pick the newest nightly at least `SOAK_DAYS` old **today**, set it as
`channel`, and update the `# adopted: <today>` line in
`rust-toolchain.toml` — `mise run soak` enforces the arithmetic. Also bump
the pre-baked toolchain in `.buildkite/linux-agent.Dockerfile`
(`mise run tools:check` fails on any drift between the image and the
tracked pins).

## Maintaining this skill

`scripts/soak/` is the law; this file only documents it — when they
disagree, fix this file. When editing, follow Anthropic's guidance:

- [Prompting best practices](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices)
- [Prompting Claude Fable 5](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-fable-5)
- [Skill authoring best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices)
- [Write an effective CLAUDE.md](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md)

Keep it concise (goal + constraints, not step enumeration), keep the
description in third person with explicit "use when" triggers, and keep
the window value in `constants.mts` rather than restating it here.
2 changes: 2 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["local>jdx/renovate-config"],
"minimumReleaseAge": "7 days",
"internalChecksFilter": "strict",
"ignorePaths": ["fixtures/**"],
"packageRules": [
{
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ jobs:
contents: read
env:
RUSTFLAGS: "-D warnings"
# Until the SOCKET_SECURITY_KEY repo secret lands this is empty and
# sfw runs in its keyless free tier — the firewall is active either
# way and upgrades itself to enterprise when the secret appears.
SOCKET_SECURITY_KEY: ${{ secrets.SOCKET_SECURITY_KEY }}
# cargo test spins LOCAL registry mocks; routing `cargo` through the
# sfw shim would wrap that traffic in the firewall proxy and mangle
# it (405s on registry writes, bodies replaced by proxy errors). The
# sentinel makes the cargo shim exec the real cargo directly —
# npm/pnpm installs stay firewalled.
SFW_SHIM_ACTIVE_CARGO: "1"
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
Expand All @@ -82,6 +92,19 @@ jobs:
- uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
with:
cache: false
- name: soak + external-tool pin gates
run: |
mise run soak
mise run tools:check
mise run test:scripts
- name: pinned package managers + socket firewall
run: |
node scripts/soak/external-tools.mts --install pnpm --install npm --install sfw --shims
node scripts/soak/external-tools.mts --print-bin >> "$GITHUB_PATH"
- name: assert pinned pms resolve through the shims
run: |
pnpm --version
npm --version
- run: node benchmarks/validate-results.mts
- run: mise run test
- run: mise run lint
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
/scratch/
/sandbox/
/bench-install.sh
/.claude/
# Local agent state stays untracked, but committed skills are allowed:
# git cannot re-include children of an excluded DIRECTORY, so exclude the
# dir's contents (/*) and negate the skills subtree.
/.claude/*
!/.claude/skills/
/crates/aube-resolver/data/primer-top*.json
/crates/aube-resolver/data/primer-top*.rkyv.zst
23 changes: 19 additions & 4 deletions .rules
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ project:
kind: Node.js package manager, Rust workspace
binary_surface: drop-in for pnpm CLI
language: Rust 2024
msrv: 1.93
msrv: 1.95 (stable floor; builds use the dated nightly pinned in rust-toolchain.toml, adopted after a 7-day soak, so PGO instrument+use share one LLVM)
async_runtime: tokio (multi-thread for install, current-thread for nested islands)
errors: miette (user-facing, top-level), thiserror (per-library crate)
error_codes: every error/warning carries a stable ERR_AUBE_*/WARN_AUBE_* identifier from aube-codes crate; bespoke exit codes for a curated subset; see error_codes section below for conventions
Expand Down Expand Up @@ -187,7 +187,7 @@ testing:

rust:
critical[5]:
- edition 2024, latest stable toolchain, msrv 1.93 (rust 1.90 default-LLD-on-Linux + workspace cargo publish available)
- edition 2024, toolchain pinned to a dated nightly in rust-toolchain.toml (adopt the newest nightly >=7 days old, same soak rule for bumps), msrv 1.95 stable floor (core::hint::cold_path stable; rust 1.90 default-LLD-on-Linux + workspace cargo publish available)
- no .unwrap()/.expect() in public library APIs or cross-crate boundaries. local-invariant unwraps where panic is genuinely impossible are ok, annotate with WHY
- crates/aube-*/ (libraries) use tracing (info!/warn!/error!/debug!/trace!). crates/aube/src/commands/*.rs CLI command impls may print to stdout via println!/writeln! when the whole point is CLI output (view, list, outdated, why, cat-index, etc.)
- cargo clippy -- -D warnings must pass with zero warnings
Expand All @@ -202,7 +202,7 @@ rust:
- shared reqwest::Client with pool, never one per request (aube-registry/src/client.rs does this right)
- DashMap for concurrent maps, OnceLock/LazyLock for init-once globals, rayon par_iter for CPU-bound parallel passes off the tokio runtime (never spawn tokio tasks for pure CPU)
- pre-size Vec/HashMap when bounds are known; SmallVec<[T; N]> for hot paths with known-small size; Arc<str>/Box<str> over String when immutable
- aube already adopts mimalloc (global allocator), sonic_rs (packument decode), BLAKE3 (non-crypto hashing). these are settled; don't re-propose them
- aube already adopts mimalloc (global allocator), sonic_rs (packument decode), BLAKE3 (non-crypto hashing), core::hint::cold_path() on rare arms of hot install loops (linker materialize, pnpm subset parser, semver caches, tar walk). these are settled; don't re-propose them
async[7]:
- tokio multi-thread runtime for install (main.rs:586), nested current_thread islands inside spawn_blocking are fine
- never block in async fn, offload via spawn_blocking (IO that can't be async, tarball decode, tar extract)
Expand Down Expand Up @@ -234,9 +234,24 @@ deps:
policy: minimize, prefer std over external, every added dep must justify >=20 LOC saved
tls: rustls (no OpenSSL / native-tls)
reqwest_features: minimal (rustls-tls + http2 + json + stream + charset + system-proxy)
supply_chain[2]:
supply_chain[4]:
- cargo audit: CVE database scan (RustSec advisories) before every release, required in CI
- cargo deny: license policy, banned crates, duplicate detection, approved sources. deny.toml checked in
- cargo min-publish-age: 7-day soak on new crate versions (.cargo/config.toml [registry] global-min-publish-age; unstable feature, active via the pinned nightly). resolver skips versions younger than the window unless already locked
- external tools: pnpm/npm/sfw/zizmor/agentshield/skillspector pinned exact with sha512 SRI in external-tools.json; installed/verified only via scripts/soak/external-tools.mts (mise run tools:install / tools:check)

soak:
window: SOAK_DAYS=7 in scripts/soak/constants.mts — the ONE source; every surface derives or is parity-checked against it
surfaces[6]:
- .cargo/config.toml global-min-publish-age ("7 days")
- rust-toolchain.toml dated nightly (channel date vs the machine-read `# adopted:` line — soak.mts enforces adopted >= channel + SOAK_DAYS)
- docs/pnpm-workspace.yaml minimumReleaseAge (10080 minutes; also the taze catalog: home — aube reads this file for docs installs, and a ROOT pnpm-workspace.yaml would re-anchor the docs install at repo root, so it must stay in docs/)
- docs/.npmrc min-release-age (7 days, npm >= 11.17 parity)
- docs/taze.config.mts maturityPeriod (imports SOAK_DAYS)
- .github/renovate.json minimumReleaseAge ("7 days", explicit — extends: presets don't count; renovate PRs commit updated lockfiles and cargo min-publish-age skips already-locked versions, so renovate itself is the only place this dep path can be soaked)
manager: .claude/skills/soak/SKILL.md is the how-to; mise run soak (check, CI-gated in test-linux) / soak:fix (syncs windows, prunes expired excludes) / deps:update (taze + cargo update, both soaked)
excludes: version-pinned minimumReleaseAgeExclude entries REQUIRE `# published: YYYY-MM-DD | removable: YYYY-MM-DD` on the line above (removable = published + 7d); bare names/globs are standing trust and need no annotation; expired pins are pruned by soak:fix
socket_firewall: CI installs sfw (free tier keyless; enterprise auto-selected when the SOCKET_SECURITY_KEY repo secret lands — the one env var every Socket product reads, no aliasing) and shims npm/yarn/pnpm/pip/pip3/uv/cargo via scripts/soak/external-tools.mts --shims; the buildkite agent image pre-bakes the same binary + shims

git:
forbidden[2]:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ codegen-units = 1
[workspace.package]
version = "1.26.0"
edition = "2024"
rust-version = "1.93"
rust-version = "1.95"
license = "MIT"
repository = "https://github.com/jdx/aube"
homepage = "https://github.com/jdx/aube"
Expand Down
3 changes: 3 additions & 0 deletions crates/aube-linker/src/materialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ impl Linker {
let target = pkg_nm_dir.join(rel_path);

if let Err(e) = self.link_file_fresh(stored, rel_path, &target) {
core::hint::cold_path();
if let Error::MissingStoreFile { .. } = &e {
invalidate_stale_index_for_package(&self.store, pkg);
}
Expand Down Expand Up @@ -785,6 +786,7 @@ impl Linker {
}
};
if let Err(e) = reflink_result {
core::hint::cold_path();
// Source-missing short-circuit avoids the misleading
// "fell back to copy" trace and the redundant copy
// attempt that would just ENOENT for the same reason.
Expand Down Expand Up @@ -840,6 +842,7 @@ impl Linker {
}
LinkStrategy::Hardlink => {
if let Err(e) = std::fs::hard_link(&stored.store_path, dst) {
core::hint::cold_path();
if !stored.store_path.exists() {
return Err(missing_source());
}
Expand Down
Loading
Loading