Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ pnpm-lock.yaml linguist-generated=true

# The root Cargo lock is selected dependency topology and must stay visible.
rust/Cargo.lock -linguist-generated

# Central Reindeer output is deterministic dependency topology.
rust/third-party/BUCK linguist-generated=true
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,28 @@ All notable changes to this project will be documented in this file.

- Fix lazy Buck stage-0 recovery to snapshot only its fingerprinted source inputs, keep unrelated Cargo product manifests out of tool derivations, and retain the observability gate when shell-entry setup is disabled.

- **Buck2 megarepo product**: add Python-free, separately cacheable `mr`,
project-typecheck, and quality targets whose runtime and project closures
compose one package/tsconfig Genie registry. The exact product is checked by
the Nix runtime boundary; admission retains asserted invalidation and hostile
seam controls, while the benchmark explicitly reports the still-coarse
package-level production source boundary instead of claiming import-level
cache granularity.

- Harden Buck foundation review contracts by recording explicit revision and execution-platform receipt identity, redacting password aliases, validating schema-v3 provenance, preserving mutation-free observability checks, narrowing generated-file markings, and leasing in-flight publications against future collection.
- Preserve pre-identity Buck receipt and dry-run compatibility while hardening dynamic ELF metadata boundaries, inspector failures, and artifact-seam mutation proofs.
- Parse dynamic ELF dependency delimiters and version-need sections structurally, including non-numeric symbol versions without admitting local definition noise.
- Preserve fixed-marker PT_INTERP paths and complete whitespace-bearing version-need names when inspecting dynamic ELF artifacts.
- Bind Buck comparison receipts to the same repository revision and execution platform, preserve delimiter-like ELF version names, and keep the Rust toolchain flake call aligned with its minimal config API.

- **Native otel-scrape product**: generate a fine-grained Buck Rust graph from
the root Cargo/Reindeer resolution domain, compile a configured static-musl
library, binary, and unit harness without Cargo actions, and package an exact
`buck-build-product/v1` archive admitted by Nix's static-ELF inspector. Keep
the required self-derived import smoke test distinct from real admission,
which now requires an externally supplied descriptor digest with no fallback
and retains a literal Nix-side platform expectation.

- **Buck2/devenv fast path**: make shell activation independent of Buck and
repository setup, expose the pinned Buck client through a source-mode local
launcher, lazily resolve stage-0 tools only for consuming tasks, and classify
Expand All @@ -35,7 +51,7 @@ All notable changes to this project will be documented in this file.
descriptor digest for the shared Buck-to-Nix product envelope. Runtime is a
required tagged union, invocation evidence is excluded from semantic product
identity, and the importer now requires an independently supplied descriptor
digest and rejects every runtime until its real inspector exists. This removes
digest and rejects every runtime without an admitted inspector. This removes
the synthetic shell import as evidence of an admitted portable product; the
input-plan fixture is now labeled `buck2-package-evidence` rather than
masquerading as a build product. Descriptor paths reject CR/LF bytes, fixed
Expand Down Expand Up @@ -86,6 +102,15 @@ All notable changes to this project will be documented in this file.

### Fixed

- **Buck2 Rust toolchain identity**: bind every consumed compiler, linker,
binutils, documentation, lint, Python, and helper-PATH input into the single
Nix-authored identity, reconstruct the complete material independently in
Buck, and fail closed when a configured tool such as the archiver is omitted.
Project a separate minimal Rust compile/product identity so changes to
clippy, rustdoc, Python, or unused binutils do not invalidate compilation or
packaging. Bind that identity at Prelude's conventional compiler `RunInfo`,
so the real OTEL compile path verifies it before invoking `rustc`.

- **Buck2 pnpm prototype scope**: retain the exact lock-derived contextual
dependency plan for `tui-core` while keeping it explicitly non-admitted. The
prototype does not fetch, unpack, normalize, or materialize package archives.
Expand Down
27 changes: 24 additions & 3 deletions buck2/rust/BUCK
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
load(":local_store.bzl", "rust_local_store_toolchain", "rust_static_binary")
load(":local_store.bzl", "rust_local_store_toolchain", "rust_static_binary", "rust_toolchain_config_integrity")

# Nix owns these values. The invoking Nix/devenv launcher supplies exact store
# paths with --config; they are command-line inputs to the local-only action.
rust_local_store_toolchain(
name = "x86_64_linux_musl_toolchain",
ar = read_config("rust_toolchain", "ar", ""),
cc = read_config("rust_toolchain", "cc", ""),
clippy_driver = read_config("rust_toolchain", "clippy_driver", ""),
contract = read_config("rust_toolchain", "contract", ""),
cxx = read_config("rust_toolchain", "cxx", ""),
dwp = read_config("rust_toolchain", "dwp", ""),
execution_platform = read_config("rust_toolchain", "execution_platform", ""),
identity_verifier = read_config("rust_toolchain", "identity_verifier", ""),
linker = read_config("rust_toolchain", "linker", ""),
nm = read_config("rust_toolchain", "nm", ""),
objcopy = read_config("rust_toolchain", "objcopy", ""),
objdump = read_config("rust_toolchain", "objdump", ""),
python = read_config("rust_toolchain", "python", ""),
ranlib = read_config("rust_toolchain", "ranlib", ""),
rustc = read_config("rust_toolchain", "rustc", ""),
rustdoc = read_config("rust_toolchain", "rustdoc", ""),
strip = read_config("rust_toolchain", "strip", ""),
target_platform = read_config("rust_toolchain", "target_platform", ""),
target_triple = read_config("rust_toolchain", "target_triple", ""),
toolchain_identity_material = read_config("rust_toolchain", "toolchain_identity_material", ""),
toolchain_identity = read_config("rust_toolchain", "toolchain_identity", ""),
tool_path = read_config("rust_toolchain", "tool_path", ""),
config_integrity_material = read_config("rust_toolchain", "config_integrity_material", ""),
config_integrity_identity = read_config("rust_toolchain", "config_integrity_identity", ""),
compile_identity_material = read_config("rust_toolchain", "compile_identity_material", ""),
compile_identity = read_config("rust_toolchain", "compile_identity", ""),
)

rust_toolchain_config_integrity(
name = "x86_64_linux_musl_config_integrity",
toolchain = ":x86_64_linux_musl_toolchain",
visibility = ["PUBLIC"],
)

rust_static_binary(
Expand Down
159 changes: 141 additions & 18 deletions buck2/rust/local_store.bzl
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
"""Exact Nix-store Rust tools for local-only target probes."""

RustLocalStoreToolchainInfo = provider(fields = [
"ar",
"cc",
"clippy_driver",
"contract",
"cxx",
"dwp",
"execution_platform",
"identity_verifier",
"linker",
"nm",
"objcopy",
"objdump",
"python",
"ranlib",
"rustc",
"rustdoc",
"strip",
"target_platform",
"target_triple",
"toolchain_identity",
"toolchain_identity_material",
"tool_path",
"compile_identity",
"compile_identity_material",
"config_integrity_identity",
"config_integrity_material",
])

_CONTRACT = "effect-utils/rust-local-store-toolchain/v1"
Expand All @@ -21,28 +36,81 @@ def _require_nix_store_executable(value, name):
if not value.startswith("/nix/store/") or "/bin/" not in value:
fail("{} must be an absolute Nix store executable".format(name))

def _require_toolchain_identity(value):
def _require_identity(value, name):
if len(value) != 71 or not value.startswith("sha256:"):
fail("toolchain_identity must be a Nix-authored sha256 identity")
fail("{} must be a Nix-authored sha256 identity".format(name))

def _identity_material(ctx):
def _require_nix_tool_path(value):
if not value:
fail("tool_path must be a non-empty list of immutable Nix store paths")
for path in value.split(":"):
if not path.startswith("/nix/store/") or not path.endswith("/bin"):
fail("tool_path entry must be an immutable Nix store bin directory: {}".format(path))

def _config_integrity_material(ctx):
return ";".join([
"ar=" + ctx.attrs.ar,
"cc=" + ctx.attrs.cc,
"clippy_driver=" + ctx.attrs.clippy_driver,
"contract=" + ctx.attrs.contract,
"cxx=" + ctx.attrs.cxx,
"dwp=" + ctx.attrs.dwp,
"execution_platform=" + ctx.attrs.execution_platform,
"identity_verifier=" + ctx.attrs.identity_verifier,
"linker=" + ctx.attrs.linker,
"nm=" + ctx.attrs.nm,
"objcopy=" + ctx.attrs.objcopy,
"objdump=" + ctx.attrs.objdump,
"python=" + ctx.attrs.python,
"ranlib=" + ctx.attrs.ranlib,
"rustc=" + ctx.attrs.rustc,
"rustdoc=" + ctx.attrs.rustdoc,
"strip=" + ctx.attrs.strip,
"target_platform=" + ctx.attrs.target_platform,
"target_triple=" + ctx.attrs.target_triple,
"tool_path=" + ctx.attrs.tool_path,
])

def _compile_identity_material(ctx):
return ";".join([
"ar=" + ctx.attrs.ar,
"cc=" + ctx.attrs.cc,
"contract=" + ctx.attrs.contract,
"cxx=" + ctx.attrs.cxx,
"execution_platform=" + ctx.attrs.execution_platform,
"linker=" + ctx.attrs.linker,
"rustc=" + ctx.attrs.rustc,
"target_platform=" + ctx.attrs.target_platform,
"target_triple=" + ctx.attrs.target_triple,
"tool_path=" + ctx.attrs.tool_path,
])

def _rust_local_store_toolchain_impl(ctx):
_require_nix_store_executable(ctx.attrs.rustc, "rustc")
_require_nix_store_executable(ctx.attrs.linker, "linker")
_require_nix_store_executable(ctx.attrs.identity_verifier, "identity_verifier")
_require_toolchain_identity(ctx.attrs.toolchain_identity)
if ctx.attrs.toolchain_identity_material != _identity_material(ctx):
fail("Rust toolchain identity material does not match the configured fields")
for name, executable in [
("ar", ctx.attrs.ar),
("cc", ctx.attrs.cc),
("clippy_driver", ctx.attrs.clippy_driver),
("cxx", ctx.attrs.cxx),
("dwp", ctx.attrs.dwp),
("identity_verifier", ctx.attrs.identity_verifier),
("linker", ctx.attrs.linker),
("nm", ctx.attrs.nm),
("objcopy", ctx.attrs.objcopy),
("objdump", ctx.attrs.objdump),
("python", ctx.attrs.python),
("ranlib", ctx.attrs.ranlib),
("rustc", ctx.attrs.rustc),
("rustdoc", ctx.attrs.rustdoc),
("strip", ctx.attrs.strip),
]:
_require_nix_store_executable(executable, name)
_require_nix_tool_path(ctx.attrs.tool_path)
_require_identity(ctx.attrs.config_integrity_identity, "config_integrity_identity")
_require_identity(ctx.attrs.compile_identity, "compile_identity")
if ctx.attrs.config_integrity_material != _config_integrity_material(ctx):
fail("Rust config-integrity material does not match the configured fields")
if ctx.attrs.compile_identity_material != _compile_identity_material(ctx):
fail("Rust compile-identity material does not match the configured fields")
if ctx.attrs.contract != _CONTRACT:
fail("unsupported Rust toolchain contract: {}".format(ctx.attrs.contract))
if ctx.attrs.execution_platform != _EXECUTION_PLATFORM:
Expand All @@ -54,30 +122,85 @@ def _rust_local_store_toolchain_impl(ctx):
return [
DefaultInfo(),
RustLocalStoreToolchainInfo(
ar = ctx.attrs.ar,
cc = ctx.attrs.cc,
clippy_driver = ctx.attrs.clippy_driver,
contract = ctx.attrs.contract,
cxx = ctx.attrs.cxx,
dwp = ctx.attrs.dwp,
execution_platform = ctx.attrs.execution_platform,
identity_verifier = ctx.attrs.identity_verifier,
linker = ctx.attrs.linker,
nm = ctx.attrs.nm,
objcopy = ctx.attrs.objcopy,
objdump = ctx.attrs.objdump,
python = ctx.attrs.python,
ranlib = ctx.attrs.ranlib,
rustc = ctx.attrs.rustc,
rustdoc = ctx.attrs.rustdoc,
strip = ctx.attrs.strip,
target_platform = ctx.attrs.target_platform,
target_triple = ctx.attrs.target_triple,
toolchain_identity = ctx.attrs.toolchain_identity,
toolchain_identity_material = ctx.attrs.toolchain_identity_material,
tool_path = ctx.attrs.tool_path,
compile_identity = ctx.attrs.compile_identity,
compile_identity_material = ctx.attrs.compile_identity_material,
config_integrity_identity = ctx.attrs.config_integrity_identity,
config_integrity_material = ctx.attrs.config_integrity_material,
),
]

rust_local_store_toolchain = rule(
impl = _rust_local_store_toolchain_impl,
attrs = {
"ar": attrs.string(),
"cc": attrs.string(),
"clippy_driver": attrs.string(),
"contract": attrs.string(),
"cxx": attrs.string(),
"dwp": attrs.string(),
"execution_platform": attrs.string(),
"identity_verifier": attrs.string(),
"linker": attrs.string(),
"nm": attrs.string(),
"objcopy": attrs.string(),
"objdump": attrs.string(),
"python": attrs.string(),
"ranlib": attrs.string(),
"rustc": attrs.string(),
"rustdoc": attrs.string(),
"strip": attrs.string(),
"target_platform": attrs.string(),
"target_triple": attrs.string(),
"toolchain_identity": attrs.string(),
"toolchain_identity_material": attrs.string(),
"tool_path": attrs.string(),
"compile_identity": attrs.string(),
"compile_identity_material": attrs.string(),
"config_integrity_identity": attrs.string(),
"config_integrity_material": attrs.string(),
},
)

def _config_integrity_impl(ctx):
toolchain = ctx.attrs.toolchain[RustLocalStoreToolchainInfo]
out = ctx.actions.declare_output("config-integrity.txt")
ctx.actions.run(
[
toolchain.identity_verifier,
toolchain.config_integrity_material,
toolchain.config_integrity_identity,
"--stamp",
out.as_output(),
],
category = "rust_toolchain_config_integrity",
env = {"PATH": "/nonexistent"},
identifier = toolchain.config_integrity_identity[7:19],
local_only = True,
)
return [DefaultInfo(default_output = out)]

rust_toolchain_config_integrity = rule(
impl = _config_integrity_impl,
attrs = {
"toolchain": attrs.exec_dep(providers = [RustLocalStoreToolchainInfo]),
},
)

Expand All @@ -87,8 +210,8 @@ def _rust_static_binary_impl(ctx):
ctx.actions.run(
[
toolchain.identity_verifier,
toolchain.toolchain_identity_material,
toolchain.toolchain_identity,
toolchain.compile_identity_material,
toolchain.compile_identity,
toolchain.rustc,
ctx.attrs.src,
"--crate-name",
Expand All @@ -109,7 +232,7 @@ def _rust_static_binary_impl(ctx):
],
category = "rust_compile",
env = {"PATH": "/nonexistent"},
identifier = "{}-{}".format(toolchain.target_triple, toolchain.toolchain_identity[7:19]),
identifier = "{}-{}".format(toolchain.target_triple, toolchain.compile_identity[7:19]),
local_only = True,
)
return [DefaultInfo(default_output = out), RunInfo(args = cmd_args(out))]
Expand Down
55 changes: 55 additions & 0 deletions buck2/rust_product.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""Exact Buck build-product packaging for one Nix-authored static Rust lane."""

BuildProductInfo = provider(fields = ["archive", "descriptor"])

def _single_output(dep):
outputs = dep[DefaultInfo].default_outputs
if len(outputs) != 1:
fail("rust_build_product requires exactly one binary output")
return outputs[0]

def _impl(ctx):
identity = ctx.attrs.compile_identity
if len(identity) != 71 or not identity.startswith("sha256:"):
fail("compile_identity must be a Nix-authored sha256 identity")
archive = ctx.actions.declare_output("artifact.tar")
descriptor = ctx.actions.declare_output("descriptor.json")
ctx.actions.run(
[
ctx.attrs._packager[RunInfo],
"product",
"--binary", _single_output(ctx.attrs.binary),
"--binary-name", ctx.attrs.binary_name,
"--target", str(ctx.label),
"--toolchain-identity", identity,
"--archive", archive.as_output(),
"--descriptor", descriptor.as_output(),
],
category = "rust_build_product",
env = {"PATH": "/nonexistent"},
identifier = ctx.attrs.binary_name,
local_only = True,
)
return [
DefaultInfo(
default_output = archive,
other_outputs = [descriptor],
sub_targets = {
"descriptor": [DefaultInfo(default_output = descriptor)],
},
),
BuildProductInfo(archive = archive, descriptor = descriptor),
]

rust_build_product = rule(
impl = _impl,
attrs = {
"binary": attrs.dep(),
"binary_name": attrs.string(),
"compile_identity": attrs.string(),
"_packager": attrs.default_only(attrs.exec_dep(
default = "toolchains//:package_evidence_tool",
providers = [RunInfo],
)),
},
)
Loading