بازگشت به مهندسی مدرن و کار با هوش مصنوعی · فصل ۵ — Shell، Workspace، Lockfile و Build Closure · 27
Exact toolchain closure and offline reproducibility
Integrate workspace, lockfile, runtime/toolchain, local artifact, environment, and clean offline verification evidence into one bounded closure manifest. میتواند «Exact Toolchain Closure و Offline Reproducibility» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
Lesson summary
Integrate workspace, lockfile, runtime/toolchain, local artifact, environment, and clean offline verification evidence into one bounded closure manifest.
میتواند «Exact Toolchain Closure و Offline Reproducibility» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
This lesson produces
میتواند «Exact Toolchain Closure و Offline Reproducibility» را در یک 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
Three green lockfiles can still produce a broken offline workspace
A bounded repository contains a pnpm JavaScript workspace, a Python project managed by uv, and a Cargo workspace. All three lockfiles are committed and routine commands are green on a developer machine. A fresh no-network reconstruction still stops: the Node identity differs from the team expectation, one local wheel is missing, and a relevant environment input was never recorded. The lockfiles did not change; the closure was incomplete.
The output of this lesson is Exact Toolchain Closure Manifest v1. It does not claim that everything is reproducible forever. It records which workspace/config files are authoritative, which tools and runtimes are actually active, each ecosystem's lock state, the local artifacts required for reconstruction, the environment/system inputs included in the claim, the clean reconstruction evidence, and the residuals that remain outside the boundary.
This is the chapter-exit integration lesson. It consumes the earlier pnpm, uv/Python, and Cargo/Rust evidence instead of re-teaching their complete command catalogs.
Three routes, one evidence bar
On the Foundation route, write the six layers first: Authority/Workspace → Tool & Runtime Identity → Locks → Local Artifacts → Clean Offline Reconstruction → Residual Boundary. Mark each layer as declared, observed, or unknown.
On the Repair route, stay on the smallest broken edge. If the lock is stable but runtime identity drifted, do not refresh the lock. If runtime identity is correct but an artifact is missing, do not change the toolchain. If only irrelevant noise changed, do not invalidate the closure without a semantic reason.
On the Experienced/Fast Path, command walkthroughs may be compressed, but exact identity, hash/inventory evidence, clean-state proof, per-tool source semantics, mutation sensitivity, target scope, and the residual-risk decision remain mandatory.
Mental model: closure is a chain, not a file
A lockfile closes only part of the state. pnpm-lock.yaml, uv.lock, and Cargo.lock each have tool-specific meaning. By themselves they do not pin Node, Python, uv, rustc, or rustup identity, and they do not automatically include the OS, linker, locale, clock, CPU, or external services in the claim.
The lesson uses six edges: authoritative workspace/config; tool/runtime identity; ecosystem locks; local artifacts; clean offline reconstruction; and residual boundary. A missing edge means the correct result is UNKNOWN or BLOCKED, not a broad conclusion borrowed from a different green signal.
Build Exact Toolchain Closure Manifest v1
Create one row per ecosystem and use shared columns only as evidence categories, not as a claim of shared flag semantics. Minimum columns are layer, authority_file_or_source, hash_or_identity, tool_runtime_target, lock_state, local_artifact_inventory, relevant_env_system_assumption, clean_offline_check, mutation_result, evidence_locator, decision, and residual_boundary.
Each value is OBSERVED, INFERRED, or UNKNOWN. Unknown evidence is visible rather than silently promoted. The manifest also names its target: a statement such as “reconstruct this fixture on the recorded OS/architecture with the recorded tools and declared local artifacts” is defensible; “the project is completely reproducible” is not.
Keep tool semantics separate while combining the evidence
For pnpm, pnpm install --offline uses packages already available in the store and fails when a required package is not local. --frozen-lockfile prevents lockfile generation/update and fails when the lockfile is missing or out of sync with the manifest. Those are pnpm semantics.
For uv, project locking and syncing have their own rules. --locked checks that the lockfile is current and errors instead of updating it; --frozen uses the lockfile without the up-to-date check. --offline constrains network use. The word “frozen” must not inherit Cargo's definition.
For Cargo, --locked asserts the existing Cargo.lock resolution, --offline prevents Cargo network access, and Cargo specifically defines --frozen as the combination of locked and offline. Rust toolchain selection is separate: rustup may select from command shorthand, RUSTUP_TOOLCHAIN, directory overrides, rust-toolchain.toml, or the default toolchain. Cargo.lock therefore does not pin the compiler.
The evidence categories can be normalized across tools—authority, identity, lock, local availability, clean reconstruction, residual—but the underlying option semantics remain source-specific.
Four examples that expose incomplete closure
Bounded baseline: hash workspace/config and lock files, record tool identities, inventory local artifacts, declare MAKNOW_PROFILE=lab as a relevant environment input, and keep noise outside the claim. Remove node_modules, .venv, and target, then run each tool's own offline/locked reconstruction. If a runtime is absent, record RUNTIME_EVIDENCE_INCOMPLETE; never manufacture a green result.
Missing artifact with stable lock: delete the required Python wheel while leaving uv.lock unchanged. A warm environment may still import successfully, but clean offline reconstruction should fail. The broken layer is local artifact availability, not lock state.
Tool/runtime drift: keep locks byte-identical while changing an expected Node/Python/Rust identity or observing a different runtime. The manifest must detect the drift before dependency-install success is promoted to a global closure claim.
Relevant versus irrelevant environment: change MAKNOW_PROFILE; because it is declared material, the closure decision must be regenerated or blocked. Change only MAKNOW_NOISE; if no claim or execution path depends on it, invalidating the closure would be overreaction.
Five shortcuts to reject
“We have three lockfiles, so the toolchain is closed.” Identity, artifact inventory, environment, and target residuals may still be open.
“All tools have offline/frozen flags, so one generic definition is enough.” Each tool owns its semantics; only evidence categories are shared.
“It worked on my machine without internet.” A warm store, .venv, or build target is not clean reconstruction evidence.
“Every environment variable must invalidate closure.” Only semantically relevant inputs belong in the contract unless there is evidence otherwise.
“Offline success means bit-for-bit reproducibility.” Native toolchains, OS, timestamps, locale, hardware, and services can remain residual inputs.
For experienced engineers: make closure a review artifact
Make the manifest diffable. A pnpm-lock.yaml, uv.lock, or Cargo.lock change maps to that ecosystem's lock row; a rust-toolchain.toml or runtime identity change maps to the identity row; an artifact inventory change remains visible even when the lock is byte-identical.
In CI, a warm verification job is not equivalent to clean offline reconstruction. A clean job removes installed/build state and uses an explicit local boundary. Missing runtimes and missing artifacts must fail closed with non-zero status.
Version strings are not always enough: for higher-value claims also retain executable path, target/platform, and selector/config evidence. Do not hash irrelevant noise merely to make the record look comprehensive.
Narrow truthful closure versus broad expensive closure
A wider boundary costs more to capture and maintain. OS image digests, linker/compiler identity, locale, and hardware may strengthen a claim only when they are actually controlled and verified. Naming them without an oracle is not closure.
Prepared stores, wheelhouses, and crate caches make disconnected reconstruction practical, but they create their own provenance and update lifecycle. This lesson inventories local artifact integrity; it does not establish upstream supply-chain trust or signing.
Containers, Nix, or Bazel may standardize more inputs later, but they do not replace boundary reasoning here. A floating image tag or an undeclared external artifact can still leave closure open.
Lab: one polyglot fixture, four mutations
TOL006-LAB1 combines three small subfixtures: pnpm, uv/Python, and Cargo/Rust. Run python setup_fixture.py, set MAKNOW_PROFILE=lab, and execute python inspect_closure.py to capture the baseline inventory.
python run_clean_reconstruction.py baseline removes installed/build state and invokes each ecosystem's own offline/locked command. If pnpm, uv, or Cargo/Rust is unavailable, the runner reports RUNTIME_EVIDENCE_INCOMPLETE and returns non-zero. Unavailable evidence is never a pass.
After reset, apply remove-python-artifact, tool-expectation-drift, and lock-drift separately. Change MAKNOW_PROFILE for the relevant-environment probe and MAKNOW_NOISE for irrelevant noise. The task is to identify which layer became invalid and which evidence remains valid—not to memorize a sequence.
Minimum defensible chapter-exit evidence
For each ecosystem retain authority/config hashes, tool/runtime identities, lock hash/state, local artifact inventory, clean-state actions, offline command/result, and an evidence locator. For the whole fixture add the relevant environment, target/system assumptions, mutation results, and the residual boundary.
The strongest green claim is bounded: on the recorded target, with the recorded tool/runtime identities and declared local closure boundary, every available ecosystem reconstructed from clean state without outbound network; material mutations changed the manifest or verification result; declared residuals remain outside the claim. If one required runtime is absent, that sentence is not allowed.
Use only ACCEPT_BOUNDED, BLOCKED_MISSING_EVIDENCE, or REGENERATE_AFTER_DRIFT as final decisions.
Assessment: diagnosis, decision, application, transfer
AS1 — Diagnosis: all three lock hashes are stable, but Node identity and rust-toolchain.toml differ from the previous manifest. Name the smallest broken layers and explain why refreshing locks is not verification.
AS2 — Decision: the team has a clean uv reconstruction, pnpm has only been exercised on a warm store, and Cargo runtime identity is missing. Choose ACCEPT_BOUNDED, BLOCKED_MISSING_EVIDENCE, or REGENERATE_AFTER_DRIFT for Exact Toolchain Closure Manifest v1 and state residual risk.
AS3 — Application: run the lab, complete the matrix, and show how wheel removal, tool-expectation drift, and relevant-environment mutation invalidate different evidence. Irrelevant noise must not invalidate the closure without a reason.
AS4 — Transfer: a second fixture changes Node/Python/Rust identities, removes one artifact, and changes one material plus one noisy environment value. Without sequence hints, produce a new manifest or a justified BLOCKED state and state what remains unproven.
Source and freshness boundary
Tool-specific claims were rechecked on 2026-09-09 only against official documentation: pnpm Workspace/install options, uv locking/syncing and CLI, Cargo build options, and rustup toolchain overrides. Those sources support component semantics; Exact Toolchain Closure Manifest v1 is a MAKNOW design, not a feature claimed by the tools.
The Bible review date remains 2026-10-17. If defaults or flag semantics change, refresh the volatile source layer without expanding the lesson into bit-identical system reproducibility, supply-chain trust, or total 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
Three lock hashes are unchanged, but Node identity and rust-toolchain.toml differ from the previous manifest. Diagnose the smallest broken closure layers and reject one tempting but invalid fix.
AS2 decision
Clean uv reconstruction exists; pnpm evidence is warm-store only; Cargo runtime identity is missing. Choose a bounded closure decision and state residual risk.
AS3 application
Run TOL006-LAB1, complete the closure matrix, and classify missing-artifact, tool-drift, and relevant-environment mutations with evidence locators.
AS4 transfer
Transfer the method to the changed fixture with new tool identities, a missing artifact, one material env input and one noise variable; produce a new bounded manifest or BLOCKED state.
Assessment rubric
- Boundary correctness — critical: identifies the smallest material closure layer and does not silently expand the claim.
- Evidence traceability — critical: every material conclusion resolves to a file/hash/command observation or is explicitly UNKNOWN.
- Mutation robustness — critical: the decision changes for material drift and stays stable for justified irrelevant noise.
- Transfer/residual risk: the method survives a changed fixture and residual OS/native/time/locale/hardware uncertainty is stated.
A green command without the surrounding closure evidence is insufficient.
References & freshness
Case studies
Lab files
- Run
python setup_fixture.py. - Set
MAKNOW_PROFILE=lab.MAKNOW_NOISEis intentionally outside the closure claim. - Run
python inspect_closure.py. The report records the exact Python interpreter used by the lab, Rust active-toolchain evidence when available, and resolved Rust path dependencies including the non-memberlocal_deps/text_fmtcrate. - Run
python run_clean_reconstruction.py baseline. A missing required runtime is non-zeroRUNTIME_EVIDENCE_INCOMPLETE; any confirmed ecosystem/tool/environment failure dominates that gap as non-zeroRECONSTRUCTION_FAIL. - Reset and apply one mutation at a time with
python mutate_fixture.py <mode>:remove-python-artifact,tool-expectation-drift,lock-drift. - For environment probes, change
MAKNOW_PROFILE(material) andMAKNOW_NOISE(noise). - Complete Exact Toolchain Closure Manifest v1 and state residual OS/native/time/locale/hardware boundaries.
No script installs tools or intentionally accesses a remote registry.
Lesson media & slides
Teaching files (download)