بازگشت به مهندسی مدرن و کار با هوش مصنوعی · فصل ۵ — Shell، Workspace، Lockfile و Build Closure · 26
Cargo workspace and Rust build/test evidence
Verify Cargo workspace/lock/build/test state and separate Rust toolchain identity from dependency locking and offline availability. میتواند «Cargo Workspace و Rust Build/Test» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
Lesson summary
Verify Cargo workspace/lock/build/test state and separate Rust toolchain identity from dependency locking and offline availability.
میتواند «Cargo Workspace و Rust Build/Test» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
This lesson produces
میتواند «Cargo Workspace و Rust Build/Test» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
Who it is for
Foundation
Explicit boundary map, worked baseline, evidence prompts, and a safe local fixture.
Repair
Diagnose one misconception, reduce the fixture, rerun the relevant probe, then restore the full case.
Experienced
Skip command walkthroughs; require artifact, mutation evidence, tradeoff judgment, and residual-risk statement.
Prerequisites
A stable Cargo.lock and green tests do not pin the compiler
A two-crate workspace commits Cargo.lock, and cargo test is green on a developer machine. On a clean machine the lock stays unchanged, but rust-toolchain.toml selects a different Rust toolchain; in another case a required local dependency is absent. These failures belong to different layers. The Cargo lock constrains Cargo dependency state, not the identity of rustc or the availability of every local/system input.
Your deliverable is Cargo Workspace Build Evidence Record v1. It binds workspace members, the Cargo lock hash, cargo/rustc/rustup identity, active toolchain and its selection file, the local-dependency boundary, locked/offline build and test results, tested scope, and residual system boundaries.
Three routes, one evidence bar
Foundation learners map members, lock state, and toolchain state before execution. Repair learners isolate the smallest mismatch: lock drift, toolchain selection, or local availability. Experienced learners may skip command walkthroughs, but hashes, tool identities, a clean target boundary, a mutation, and residual-risk judgment remain mandatory.
Mental model: workspace → lock + toolchain → local inputs → build/test evidence
The root Cargo.toml defines the workspace/member boundary. Workspace members share a root Cargo.lock, while Rust toolchain selection is controlled through a separate mechanism such as rust-toolchain.toml, rustup overrides, or an explicit toolchain selection. A build consumes those layers plus source and locally available dependencies. cargo test then exercises only the test targets that actually run.
Do not collapse four claims into one: dependency resolution is constrained, compiler/toolchain identity is known, required inputs are locally available, and the current tests pass. Each needs its own evidence.
Build Cargo Workspace Build Evidence Record v1
For each probe, record workspace_members, cargo_lock_hash, cargo_identity, rustc_identity, rustup_active_toolchain, toolchain_file_hash, local_dependency_boundary, locked_offline_build, test_result, tested_scope, and residual_system_boundary. Label conclusions OBSERVED, INFERRED, or UNKNOWN, with an evidence reference.
Establish the member set first, then record lock and toolchain state independently. Delete target/ before bounded build/test evidence. If a required executable or toolchain is unavailable, record that fact rather than fabricating a runtime result.
Current Cargo and rustup semantics within this lesson boundary
Current Cargo documentation defines a workspace as a set of packages managed together and states that workspace packages share a root Cargo.lock. --locked asserts that dependency versions remain exactly as represented by the existing lock and fails when the lock is missing or would need to change. --offline prevents Cargo from accessing the network and restricts it to locally available state. In Cargo, --frozen is equivalent to combining --locked and --offline; that meaning must not be imported from uv or pnpm.
rustup is a separate layer. Toolchain selection can come from command-line shorthand, RUSTUP_TOOLCHAIN, a directory override, rust-toolchain.toml, or the default toolchain. rustup show provides independent evidence of the active toolchain. Therefore, an unchanged Cargo.lock does not establish unchanged compiler identity.
cargo test also has a scope. A green suite shows that the executed test targets passed under the recorded context. It does not cover untested behavior, native/linker state, or a deployment environment that was never exercised.
Three examples that separate failure layers
Baseline: a virtual workspace has two members. Record root manifest and lock hashes, cargo/rustc/rustup identity, and the active toolchain. Delete target/, then run cargo build --workspace --locked --offline and cargo test --workspace --locked --offline. The result is evidence only for that recorded context.
Manifest–lock drift: change a member version in a manifest without regenerating the lock. If locked build would require a lock update, the failure belongs to LOCK_CONSISTENCY; verification must not silently refresh the lock.
Toolchain mutation with a constant lock: leave Cargo.lock untouched and change only the toolchain-file declaration. The evidence record is already different before compilation. If that toolchain is not installed locally, classify the result as TOOLCHAIN_UNAVAILABLE_OR_MISMATCH, not a broken dependency lock.
Four shortcuts that create false confidence
“Cargo.lock pins rustc.” Repair: record rustc --version, the active rustup toolchain, and toolchain-file hash independently.
“cargo test is green, so the application is correct.” Repair: state tested_scope and retain one deliberately untested behavior as a counterexample.
“--frozen means the same thing in every tool.” Repair: use Cargo’s own documentation; for Cargo it combines the locked and offline constraints.
“An offline failure means the lock is wrong.” Repair: keep the lock constant and mutate local dependency availability separately. Missing local input can fail with a perfectly unchanged lock.
For experienced engineers: make build evidence reviewable
In CI, store the Cargo.lock hash beside cargo --version, rustc --version, and the active toolchain. A lock change and a rust-toolchain.toml change are separate review artifacts. A clean target/ plus locked/offline execution reduces ambiguity from build residue, but system linkers, native libraries, target components, and build-script side effects remain explicit residual boundaries.
For large monorepos, record package selection as well. A green default member is not evidence that every workspace member was built and tested.
Precise pinning versus maintenance cost
Pinning a specific Rust release can reduce compiler drift, but the toolchain must remain available and managed. Using stable is simpler but makes exact identity more time-dependent. In either case the record must capture what was actually active.
Offline validation is useful but only constrains Cargo’s network behavior and local availability; it is not full OS/linker closure. Vendoring dependencies or pre-populating local state can support disconnected builds, but introduces its own provenance and update workflow. This lesson does not claim bit-identical binaries.
Lab: a small workspace with independent mutations
Use TOL005-LAB1. python setup_fixture.py creates a fresh working copy with two workspace members plus one non-member local path dependency. python inspect_context.py records members, hashes, tool identities, and the resolved local-dependency boundary. When Cargo/Rust/rustup are available with the declared toolchain installed, python run_cargo_probe.py baseline deletes target/ and executes locked/offline build and test. Reset between the independent mutations: manifest-lock-drift, toolchain-change, missing-local-dep, and untested-behavior. The missing-local-dep mutation removes only the non-member path dependency, so workspace membership stays unchanged.
The lab requires no network. Before the toolchain mutation runner invokes anything, it checks whether the declared toolchain is locally installed and never attempts installation. If cargo/rustup are unavailable, record RUST_TOOLCHAIN_UNAVAILABLE; do not invent runtime evidence.
Minimum defensible evidence
Keep the member set and root manifest, exact Cargo.lock hash, cargo/rustc/rustup identities, active toolchain and toolchain-file hash, local-dependency state, clean-target declaration, locked/offline command/result, test result, tested scope, and residual system boundary.
At minimum distinguish WORKSPACE_MEMBERSHIP, LOCK_CONSISTENCY, RUST_TOOLCHAIN_IDENTITY, LOCAL_DEPENDENCY_AVAILABILITY, BUILD_EXECUTION, TEST_SCOPE, SYSTEM_RESIDUAL, and UNKNOWN_OR_MULTIPLE. The strongest green claim is bounded: the recorded workspace built under the recorded lock/toolchain/local-input context and the recorded test targets passed.
Assessment: diagnosis, decision, application, transfer
AS1 — Diagnosis: the lock is unchanged but rust-toolchain.toml changed. Identify the smallest changed boundary and the evidence needed to evaluate it.
AS2 — Decision: a team supplies Cargo.lock and a green cargo test log, but no member set, rustc/rustup identity, or offline/local-availability evidence. Decide ACCEPT, REJECT, or DEFER for the evidence record and state residual risk.
AS3 — Application: execute the fixture, complete the matrix, and classify lock-drift, toolchain-change, and missing-local-dependency mutations independently.
AS4 — Transfer: a second workspace changes its toolchain declaration and removes one local dependency. Without sequence hints, state which prior evidence remains valid, which evidence is invalidated, and what must be verified again.
Source and freshness boundary
Tool-specific claims are bounded to official Cargo and rustup documentation rechecked on 2026-09-09. Current Cargo documentation still describes the shared workspace lock, defines --locked and --offline separately, and defines --frozen as their combination. Current rustup documentation still describes toolchain-selection precedence and repository toolchain files/overrides independently from Cargo.lock.
The Bible review-due date is 2026-10-17. If flag semantics, workspace selection, or rustup override precedence changes, refresh only the volatile source layer without expanding the lesson into total system reproducibility or universal correctness.
Assessment
There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.
AS1 diagnosis
AS2 decision
AS3 application
AS4 transfer
Assessment rubric
- Boundary correctness (critical): member/lock/toolchain/local-input/test boundaries are separated; no silent scope expansion.
- Evidence traceability (critical): every material conclusion points to an observable or is explicitly UNKNOWN.
- Mutation robustness (critical): lock drift, toolchain change, and missing local dependency are classified at the correct layer.
- Transfer and residual risk: changed-context reasoning adapts the method and states what remains unproven.
A green cargo test alone cannot satisfy the rubric.
References & freshness
Case studies
Lab files
This lab separates Cargo workspace/lock evidence from Rust toolchain identity and non-member local path-dependency availability.
python setup_fixture.pypython inspect_context.pypython run_cargo_probe.py baseline- Reset before each mutation:
manifest-lock-drift,toolchain-change,missing-local-dep,untested-behavior.
The fixture keeps math_core and cli_app as the two workspace members and uses a separate text_fmt path dependency outside the member set. missing-local-dep removes only text_fmt.
No network is required. The runner never installs a missing toolchain. Missing Cargo/Rust, missing rustup selection evidence, or an unavailable declared toolchain returns a non-zero fail-closed status; do not reinterpret that as a green build/test result.
Lesson media & slides
Teaching files (download)