oficina / docs Public

Normalize compiler paths in unprivileged Linux builds

Paul Campbell pushed by codex agent, operated by paul@keymail.dev bc7702edf96198906e104eeaacb5b93ed6467b91 parent ce164ea
3 files changed, +43 −14
  • .amadan/README.md +8 −0
  • internal/core/testdata/docs_core.wasm binary
  • scripts/build-wasm.sh +35 −14

CI passed — run details

diff --git a/.amadan/README.md b/.amadan/README.md
index 4e8ba82..fc429c4 100644
--- a/.amadan/README.md
+++ b/.amadan/README.md
@@ -73,3 +73,11 @@ fail-closed properties that matter now
development`, a fixed port, and a scratch database — one command to see
the app in a browser, signed in for real via a magic link logged to the
terminal instead of mailed.
+
+The embedded WASM is built on Linux amd64 using fixed `/work`,
+`/usr/local/cargo` and `/usr/local/rustup` paths. Rust/Cargo's crate identities
+otherwise change code ordering across hosts, even with remapped source paths.
+Linux amd64 uses unprivileged bubblewrap when available; other hosts use the
+pinned Rust Docker image. Install Docker on development Macs. Both the artifact
+builder and containment tests use this path; the freshness comparison remains
+byte-for-byte. Docker caches and writable targets are separate from source.
diff --git a/internal/core/testdata/docs_core.wasm b/internal/core/testdata/docs_core.wasm
index 4b7828f..53decb9 100755
Binary files a/internal/core/testdata/docs_core.wasm and b/internal/core/testdata/docs_core.wasm differ
diff --git a/scripts/build-wasm.sh b/scripts/build-wasm.sh
index 012fc7f..d277b38 100755
--- a/scripts/build-wasm.sh
+++ b/scripts/build-wasm.sh
@@ -8,26 +8,47 @@ cd "$(dirname "$0")/.."
# Doc::with_client_id() both draw entropy this build has no safe source
# for. A doc comment alone has been wrong, or gotten around, more than
# once; this is the actual enforcement.
-if [[ "${1:-}" != "--build-only" ]]; then
+if [[ "${1:-}" != "--build-only" && "${1:-}" != "--canonical-build" ]]; then
cargo clippy --manifest-path core/Cargo.toml --all-targets -- -D warnings -D clippy::disallowed_methods
fi
-# Rust 1.98 emits different code on macOS even for the same wasm target.
-# The checked-in artifact and its containment tests use Linux amd64 everywhere.
-if [[ "$(uname -s)/$(uname -m)" != "Linux/x86_64" ]]; then
- command -v docker >/dev/null || { echo "build-wasm: Docker is required for the canonical Linux amd64 build" >&2; exit 1; }
+# Rust/Cargo crate identities affect code ordering even after path remapping.
+# Build on Linux amd64 at fixed source/toolchain paths on every host.
+if [[ "${1:-}" == "--canonical-build" ]]; then
+ [[ "$(uname -s)/$(uname -m)" == "Linux/x86_64" && "$(pwd)" == /work \
+ && "$CARGO_HOME" == /usr/local/cargo && "$RUSTUP_HOME" == /usr/local/rustup ]] \
+ || { echo "build-wasm: invalid canonical build environment" >&2; exit 1; }
+ export CARGO_TARGET_DIR=/work/core/target RUSTUP_TOOLCHAIN=1.98.0
+else
out="core/target/wasm32-unknown-unknown/release/docs_core.wasm"
mkdir -p "$(dirname "$out")"
temporary=$(mktemp "${out}.XXXXXX")
trap 'rm -f "$temporary"' EXIT
- target_key=$(printf %s "$(pwd)" | shasum -a 256 | cut -c1-16)
- docker run --rm --platform linux/amd64 \
- --mount "type=bind,source=$(pwd),target=/work,readonly" \
- --mount "type=volume,source=oficina-docs-wasm-target-${target_key},target=/work/core/target" \
- --mount type=volume,source=oficina-docs-wasm-cargo,target=/usr/local/cargo \
- --mount type=volume,source=oficina-docs-wasm-rustup,target=/usr/local/rustup \
- --workdir /work \
- rust@sha256:8aea3a845c48caac4091a8d0e6494d213061f8f014dc2f5a5f1a88a1a8c9f301 \
- bash -ec 'rustup target add wasm32-unknown-unknown >&2; ./scripts/build-wasm.sh --build-only >&2; cat core/target/wasm32-unknown-unknown/release/docs_core.wasm' > "$temporary"
+ if [[ "$(uname -s)/$(uname -m)" == "Linux/x86_64" ]] && command -v bwrap >/dev/null; then
+ cargo_home=$(cd "${CARGO_HOME:-$HOME/.cargo}" && pwd)
+ rustup_home=$(cd "${RUSTUP_HOME:-$HOME/.rustup}" && pwd)
+ mkdir -p core/target/canonical-linux-amd64
+ bwrap --tmpfs / \
+ --ro-bind /usr /usr --tmpfs /usr/local \
+ --ro-bind /bin /bin --ro-bind /lib /lib --ro-bind /lib64 /lib64 \
+ --ro-bind /etc /etc --bind /tmp /tmp --proc /proc --dev /dev \
+ --ro-bind "$(pwd)" /work \
+ --bind "$(pwd)/core/target/canonical-linux-amd64" /work/core/target \
+ --bind "$cargo_home" /usr/local/cargo --ro-bind "$rustup_home" /usr/local/rustup \
+ --chdir /work --setenv CARGO_HOME /usr/local/cargo --setenv RUSTUP_HOME /usr/local/rustup \
+ --setenv PATH /usr/local/cargo/bin:/usr/local/bin:/usr/bin:/bin \
+ bash -ec './scripts/build-wasm.sh --canonical-build >&2; cat core/target/wasm32-unknown-unknown/release/docs_core.wasm' > "$temporary"
+ else
+ command -v docker >/dev/null || { echo "build-wasm: install Docker, or bubblewrap on Linux amd64" >&2; exit 1; }
+ target_key=$(printf %s "$(pwd)" | shasum -a 256 | cut -c1-16)
+ docker run --rm --platform linux/amd64 \
+ --mount "type=bind,source=$(pwd),target=/work,readonly" \
+ --mount "type=volume,source=oficina-docs-wasm-target-${target_key},target=/work/core/target" \
+ --mount type=volume,source=oficina-docs-wasm-cargo,target=/usr/local/cargo \
+ --mount type=volume,source=oficina-docs-wasm-rustup,target=/usr/local/rustup \
+ --workdir /work \
+ rust@sha256:8aea3a845c48caac4091a8d0e6494d213061f8f014dc2f5a5f1a88a1a8c9f301 \
+ bash -ec 'rustup target add wasm32-unknown-unknown >&2; ./scripts/build-wasm.sh --canonical-build >&2; cat core/target/wasm32-unknown-unknown/release/docs_core.wasm' > "$temporary"
+ fi
mv "$temporary" "$out"
exit 0
fi