بازگشت به مهندسی مدرن و کار با هوش مصنوعی · فصل ۵ — Shell، Workspace، Lockfile و Build Closure · 23
pnpm Workspaces و Lockfile Discipline
میتواند «pnpm Workspaces و Lockfile Discipline» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
خلاصهٔ درس
میتواند «pnpm Workspaces و Lockfile Discipline» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
خروجی این درس
میتواند «pnpm Workspaces و Lockfile Discipline» را در یک workspace محدود طوری پیکربندی کند که dependency/toolchain state قابل تکرار و قابل بررسی باشد.
lockfile هست، اما clean offline install هنوز fail میشود
یک workspace دو-package با pnpm روی سیستم توسعهدهنده بدون مشکل install میشود. بعد دو تغییر مستقل ایجاد میکنیم: در یک package.json range وابستگی عوض میشود ولی pnpm-lock.yaml بهروزرسانی نمیشود؛ جدا از آن، یک artifact لازم از store محلی آمادهشده حذف میشود. repeat install روی محیط warm ممکن است مشکل دوم را پنهان کند، چون state قبلی هنوز وجود دارد.
خروجی این درس pnpm Dependency Closure Record v1 است. در این artifact چهار سؤال جدا میمانند: کدام dependency باید حتماً داخل workspace محلی resolve شود، آیا manifestهای فعلی بدون دستزدن به lock با pnpm-lock.yaml سازگارند، آیا مرز artifact/store محلی برای clean offline reconstruction کافی است، و دقیقاً کدام pnpm/runtime آزمایش شده است.
claim عمداً محدود است. pass شدن این record، OS closure، native libraryها، درستبودن build یا bit-for-bit reproducibility را ثابت نمیکند.
سه مسیر یادگیری، یک معیار evidence
در مسیر Foundation قبل از commandها مرزها را روشن میکنی: workspace membership، manifest intent، lock consistency، local artifact availability و clean installed state. در مسیر Repair فقط misconception خراب را جدا میکنی و probe مربوط به همان مرز را دوباره اجرا میکنی. در Experienced / Fast Path walkthrough حذف میشود، اما hashها، clean-state evidence، mutation response و residual risk باقی میمانند.
قبل از هر probe سؤال را بنویس: «آیا این dependency فقط باید به package محلی workspace resolve شود؟»، «آیا این manifestها بدون تغییر lock قابل قبولاند؟» و «آیا این clean target فقط با store آمادهشده قابل بازسازی است؟». command فقط evidence همان سؤال است، نه certificate برای کل سیستم.
مدل ذهنی: Manifest → Lockfile → Store → clean installed tree
زنجیره evidence را پنج لایه نگه دار:
- Workspace/manifest layer:
pnpm-workspace.yamlمرز workspace را مشخص میکند و manifest هر package dependency intent را declare میکند.workspace:رفتار خاص pnpm برای الزام resolution به package محلی workspace است. - Lock consistency layer:
pnpm-lock.yamlstate resolution را ثبت میکند. install با frozen flag صریح بررسی میکند که بدون ساختن یا تغییر lock بتوان جلو رفت؛ manifest/lock drift این gate را fail میکند. - Artifact availability layer: offline mode دریافت dependency را به packageهایی که در store محلی در دسترساند محدود میکند. lock صحیح میتواند وجود داشته باشد اما artifact لازم محلی نباشد.
- Clean installed-state layer:
node_modulesیا store گرم ممکن است input گمشده را پنهان کند. assessed run از clean target و store boundary مشخص شروع میشود. - Environment identity: نسخه pnpm و runtime را ثبت کن. lockfile بهتنهایی OS، native library، runtime، registry یا همهٔ build inputها را pin نمیکند.
این لایهها مرتبطاند اما جای هم را نمیگیرند.
pnpm Dependency Closure Record v1 را بساز
برای هر dependency/probe مهم حداقل این فیلدها را ثبت کن: workspace_member، manifest_hash، dependency_intent، lock_hash، lock_consistent، store_boundary، offline_clean_result، failure_layer، pnpm_identity، runtime_identity، evidence و residual_boundary.
سه state را دقیق استفاده کن:
OBSERVED: مستقیم از file، hash، command output یا fixture کنترلشده دیده شده؛INFERRED: conclusion محدود که از observationها ساخته شده؛UNKNOWN: evidence لازم نداریم یا contradiction حل نشده است.
در verificationی که قرار است سازگاری lock موجود را بسنجد، lock را refresh نکن. بهروزرسانی lock در development میتواند کار درست باشد، اما evidence مربوط به سؤال «آیا lock قبلی frozen-consistent بود؟» را از بین میبرد.
frozen و offline دو سؤال متفاوت را جواب میدهند
مستندات رسمی جاری pnpm 12.x میگویند workspace: resolution را به package محلی workspace محدود میکند. بنابراین اگر package/version محلی موردنیاز وجود نداشته باشد، install fail میشود و registry replacement بهعنوان جایگزین بیصدا پذیرفته نمیشود.
همان مستندات --frozen-lockfile را حالتی تعریف میکنند که lockfile را تولید یا بهروزرسانی نمیکند و اگر lock با manifest sync نباشد، update لازم باشد یا lock وجود نداشته باشد، install fail میشود. در lab flag را صریح بنویس؛ روی default محیط حساب نکن.
--offline سؤال دیگری دارد: pnpm فقط packageهایی را که در store محلی موجودند استفاده میکند و اگر package لازم محلی پیدا نشود install fail میشود. پس «frozen pass شد» مساوی «clean offline reconstruction pass میشود» نیست؛ و «روی سیستم warm من offline pass شد» هم کاملبودن artifact boundary کنترلشده را ثابت نمیکند.
مثال کارشده: یک drift failure و یک artifact failure
Baseline: workspace شامل apps/cli و packages/core است. apps/cli با workspace:* به @closure/core وابسته است. hash manifestها، lock hash، pnpm/runtime identity و store boundary ثبت میشوند. سپس clean install با frozen و offline constraints صریح اجرا میشود. اگر pass شود، conclusion فقط برای همین manifest/lock/store/tool context معتبر است.
Manifest-drift mutation: range یک dependency را در manifest تغییر بده ولی lock را ثابت نگه دار. failure layer مورد انتظار LOCK_CONSISTENCY است. در این probe نباید lock را repair کنی.
Missing-artifact mutation: manifest و lock baseline را restore کن و بعد یک artifact لازم را از prepared store boundary حذف کن. ممکن است lock هنوز consistent باشد اما clean offline reconstruction fail شود. failure layer اینجا OFFLINE_ARTIFACT_AVAILABILITY است.
این دو failure یکی نیستند. اگر فقط بنویسی «install fail شد»، مرز evidence را از دست دادهای.
چهار میانبُر که closure evidence را خراب میکنند
«lockfile commit شده، پس offline reproducibility ثابت است.» repair: clean offline reconstruction را روی store boundary مشخص آزمایش کن.
«frozen یعنی حتی با manifest متفاوت همان lock را استفاده کن.» repair: manifest را mutate کن و ببین frozen gate باید mismatch را رد کند، نه اینکه silently قبولش کند.
«روی سیستم من pass شد، پس closure کامل است.» repair: install target را reset کن و warm state را از prepared store جدا نگه دار.
«workspace: فقط syntax ظاهری است.» repair: workspace member لازم را حذف/rename کن و بررسی کن local-workspace intent دیگر قابل satisfy شدن نیست.
برای مهندس باتجربه: verification را reviewable کن
در repo واقعی، lock refresh و lock verification را دو event جدا نگه دار. وقتی تغییر dependency واقعاً lock جدید میخواهد، lock را آگاهانه regenerate کن و diff آن را review کن. وقتی سؤال این است که committed state بازسازی میشود یا نه، frozen check غیرمخرب اجرا کن.
برای offline یا محیطهای محدود، artifact boundary را نامگذاری کن. store آمادهشده روی یک machine بهصورت خودکار evidence برای همهٔ platformها یا native dependencyها نیست. pnpm/runtime identity و مرزهای OS/native را صریح ثبت کن.
CI سبز evidence مفیدی است، اما فقط برای همان input و environment که واقعاً اجرا شده. Closure Record باید این boundary را قابل دیدن کند، نه اینکه یک green job را guarantee عمومی جلوه دهد.
verification سختگیرانه convenience را کم میکند؛ هدف همین است
در development، install عادی میتواند با تغییر dependency intent نیاز به lock update داشته باشد و این رفتار مشروع است. frozen verification عمداً این convenience را میبندد تا drift دیده شود. offline verification acquisition را محدودتر میکند و در نتیجه prepared artifact boundary لازم دارد.
این lesson توصیه نمیکند همه همیشه offline کار کنند. frozen و offline اینجا ابزار evidence هستند؛ وقتی سؤال reproducibility/inspectability committed dependency state است از آنها استفاده کن. full toolchain closure در scope درسهای بعدی است.
Lab: baseline، بعد هر بار فقط یک mutation
در fixture محلی TOL002-LAB1 هر اجرای مستقل را با python setup_fixture.py شروع کن؛ این reset فقط داخل fixture بستهبندیشدهٔ درس عمل میکند. fixture شامل workspace declaration، manifestها، lock snapshot، یک tarball محلی واقعی با integrity ثبتشده، reset/mutation tools و execution plan برای pnpm است. probe ابتدا store ایزوله و محلی fixture را از همان tarball آماده میکند و بعد frozen/offline install را روی همان store اجرا میکند؛ host/global store مرز assessed نیست. credential یا privileged host change لازم نیست.
ابتدا hashهای baseline و execution context محدود را ثبت کن: resolved tool/runtime identity، platform، cwd، integrity artifact و مسیر صریح store محلی fixture. target را reset کن و در محیطی که pnpm در دسترس است frozen/offline probe را اجرا کن. بعد سه mutation را مستقل اجرا کن: manifest drift بدون lock update، حذف یک artifact آمادهشده، و حذف/rename یک workspace member که با workspace intent reference شده است. بین mutationها reset انجام بده.
برای هر run فقط کوچکترین failure layer پشتیبانیشده را classify کن. transfer fixture هم manifest state و هم artifact availability را تغییر میدهد و sequence جواب آماده ندارد. تصمیم بگیر failure از LOCK_DRIFT، ARTIFACT_UNAVAILABLE، WORKSPACE_LOCAL_RESOLUTION، بیش از یک مرز مستقل یا DEFER است.
حداقل evidence قابل دفاع
Closure Record دفاعپذیر باید manifest/lock hash، pnpm/runtime identity صریح، clean target، store/artifact boundary، frozen/offline probe، mutation evidence و bounded decision داشته باشد. warm-state success بهتنهایی کافی نیست.
اگر declared state با observed output contradiction دارد، conclusion را به زور نساز؛ contradiction را نگه دار و probe را کوچکتر کن. اگر pnpm در execution environment وجود ندارد، آن را missing runtime evidence ثبت کن و simulated success را جای observation واقعی ننویس.
statement نهایی باید بگوید چه چیزی ثابت شد و چه چیزی نشد. مثال: «این workspace/lock/store snapshot با pnpm/runtime ثبتشده بازسازی شد؛ OS-native closure و build correctness آزمایش نشد.»
Assessment: تشخیص، تصمیم، اجرا و انتقال
AS1 — Diagnosis: کسی میگوید وجود lockfile clean offline install را تضمین میکند. کوچکترین evidence boundary گمشده و observation تصمیمگیر را مشخص کن.
AS2 — Decision: manifest/lock hash و یک warm install موفق داری اما clean offline probe نداری. برای pnpm Dependency Closure Record v1 تصمیم ACCEPT، REJECT یا DEFER بده و residual risk را بنویس.
AS3 — Application: baseline fixture را اجرا کن، Closure Record را کامل کن و manifest-drift و missing-artifact mutation را بدون تغییر lock در verification اجرا کن.
AS4 — Transfer: در fixture تغییرکرده تعیین کن failure مربوط به lock drift، artifact unavailability، workspace-local resolution یا چند boundary مستقل است. بگو چه چیزی هنوز اثبات نشده است.
critical dimensionها عبارتاند از workspace-local resolution، manifest-lock consistency، offline artifact sufficiency، clean-state verification و scope ادعای reproducibility.
مرز source و freshness
claimهای tool-specific به مستندات رسمی جاری pnpm محدود هستند. در 2026-09-08 صفحه Workspace نسخه 12.x همچنان root workspace configuration و workspace: local-only resolution constraint را مستند میکند. صفحه install نیز رفتار --frozen-lockfile برای عدم update و fail روی out-of-sync state و رفتار --offline برای استفاده از store محلی را تأیید میکند.
review-due ثبتشده در Bible برابر 2026-10-17 است. defaultها و implementation detail میتوانند تغییر کنند، بنابراین lesson از flag صریح استفاده میکند و pnpm/runtime identity را ثبت میکند. semantics flagهای همنام به package managerهای دیگر تعمیم داده نمیشود.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
AS1 diagnosis
A teammate says the committed lockfile guarantees a clean offline install. Diagnose the smallest missing evidence boundary and name the observation that would decide it.
AS2 decision
You have manifest/lock hashes and a successful warm install, but no clean offline probe. Decide ACCEPT, REJECT, or DEFER for pnpm Dependency Closure Record v1 and state residual risk.
AS3 application
Run the baseline fixture, complete the closure record, then execute manifest-drift and missing-artifact mutations without updating the lock during verification.
AS4 transfer
On the transfer fixture, determine whether failure is lock drift, artifact unavailability, workspace-local resolution, or multiple independent boundaries. State what remains unproven.
ملاکهای ارزیابی (rubric)
- Boundary correctness — critical: separates workspace-local resolution, lock consistency, and artifact availability.
- Evidence traceability — critical: every material conclusion cites a file/hash/command observation or remains unknown.
- Mutation robustness — critical: manifest drift and missing-artifact mutations change the classification at the correct layer.
- Clean-state discipline — critical: warm state is not accepted as proof of clean reconstruction.
- Transfer and residual risk: method transfers to a changed fixture and unproven OS/runtime/build boundaries remain explicit.
A polished explanation cannot compensate for a failure in a critical dimension.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
python setup_fixture.pyو سپسpython inspect_closure.pyرا اجرا کن. snapshot محدود execution context را ثبت کن: identity و resolved executable مربوط به Python/Node/pnpm در صورت وجود، platform، cwd، hashهای manifest/lock و مرز نامگذاریشدهٔ artifact/store.- در محیطی که pnpm موجود است baseline را reset کن و
python run_pnpm_probe.pyرا اجرا کن. probe فقط store ایزوله و محلی fixture را از tarball محلی بستهشده آماده میکند و سپسpnpm install --frozen-lockfile --offline --ignore-scripts --store-dir <fixture-local-store>را اجرا میکند.PNPM_UNAVAILABLEsuccess نیست. - قبل از هر mutation reset کن:
manifest-drift،delete-store-artifactوremove-workspace-member. mutation مربوط به artifact همان tarball واقعی مورد استفاده برای آمادهسازی store ایزوله را حذف میکند. - فقط کوچکترین failure layer پشتیبانیشده را classify کن و
dependency_closure_record.csvرا کامل کن؛ output دقیق command را به evidence وصل کن. - برای AS4 از
python setup_fixture.py --transferاستفاده کن. transfer fixture عمداً بیش از یک boundary تغییرکرده دارد و sequence پاسخ آماده ندارد.
مرز ایمنی: reset/probe فقط TOL002-LAB1/learner/work و prepared_store/pnpm-store محلی همان fixture را تغییر میدهند. host/global pnpm store، credential یا تنظیمات privileged تغییر نمیکند.
tarball بستهشده و integrity ثبتشده causal boundary مربوط به artifact sufficiency را قابل review میکنند. رفتار واقعی pnpm فقط با execution واقعی learner evidence است؛ نبود pnpm یعنی evidence ناقص، نه success شبیهسازیشده.
رسانه و اسلایدهای درس
فایلهای آموزشی (دانلود)