بازگشت به مهندسی مدرن و کار با هوش مصنوعی · فصل ۵ — Shell، Workspace، Lockfile و Build Closure · 21
Shell, Process و Filesystem برای توسعه مدرن
میتواند در یک سناریوی محدود «Shell, Process و Filesystem برای توسعه مدرن» را اجرا کند، مرز ادعا را مشخص کند و evidence قابل بررسی تحویل دهد.
خلاصهٔ درس
میتواند در یک سناریوی محدود «Shell, Process و Filesystem برای توسعه مدرن» را اجرا کند، مرز ادعا را مشخص کند و evidence قابل بررسی تحویل دهد.
خروجی این درس
میتواند در یک سناریوی محدود «Shell, Process و Filesystem برای توسعه مدرن» را اجرا کند، مرز ادعا را مشخص کند و evidence قابل بررسی تحویل دهد.
پیشنیازها
وقتی همان دستور، فایل دیگری را تغییر میدهد
یک فرمان آشنا را در دو ترمینال اجرا میکنی. متن فرمان تقریباً یکسان است، هر دو بار process با exit status 0 تمام میشود، اما نتیجهٔ فایل یکی نیست. در ترمینال اول فایل مورد انتظار تغییر کرده؛ در دومی فایلی همنام در پوشهٔ دیگری تغییر کرده است. همزمان یک مقدار محیطی مثل DEMO_MODE رفتار child process را عوض کرده و پیامی در stderr بوده که اگر فقط stdout را دیده باشی، از دست رفته است.
مسئلهٔ این درس حفظکردن فرمانهای Shell نیست. باید بتوانی Execution Context Trace v1 بسازی: یک trace محدود که نشان دهد چه shell/runtime boundaryای درگیر بوده، process دقیقاً کجا اجرا شده، executable واقعی چه بوده، چه argv و environment غیرحساس و مرتبطی وارد process شده، stdout و stderr و exit status چه بودهاند، و کدام اثر filesystem واقعاً قابل اثبات است.
قاعدهٔ مرکزی ساده است: command text تمام execution نیست. اگر یک نتیجه به cwd، executable resolution، environment، stream یا file identity وابسته است، آن مرز باید به evidence تبدیل شود. این درس اثبات نمیکند که application در همهٔ محیطها درست است و exit 0 را هم معادل correctness نمیگیرد.
سه مسیر، یک evidence bar
در مسیر Foundation اصطلاحها و مرزها صریحترند: cwd، executable resolution، argv، selected environment، stdout، stderr، exit status و file effect را جدا میکنی و یک baseline هدایتشده میسازی. در مسیر Repair فقط به اولین سوءبرداشت برمیگردی؛ مثلاً اگر exit status را درست میخوانی اما relative path را file identity فرض میکنی، تمرین روی cwd → path resolution → file hash متمرکز میشود.
در Experienced / Fast Path walkthrough فرمانها کوتاه میشود، اما artifact، mutation و residual uncertainty حذف نمیشوند. تجربهٔ زیاد با terminal مجوز این نیست که pwd، PATH، streamها یا file hash را حدس بزنی.
قبل از ادامه سه سؤال را پاسخ بده: process در چه cwdای اجرا شد؟ کدام observable میتواند بین دو توضیح رقیب تمایز بگذارد؟ اگر process سبز بود، کدام evidence مستقل هنوز میتواند claim تو را رد کند؟
مدل ذهنی: Shell context → Process → Streams/Filesystem → تصمیم محدود
یک invocation را به چهار بخش جدا تبدیل کن:
- Shell/runtime context: shell یا runner، current directory و قواعد resolution که برای همان محیط واقعاً به کار رفتهاند. اگر از Bash-specific behavior استفاده میکنی، همانجا برچسب Bash بزن؛ آن را به همهٔ shellها تعمیم نده.
- Process inputs: executable واقعی،
argvو فقط environmentهای مرتبط و غیرحساس. dump کردن کل environment evidence بهتر نیست و میتواند secret نشت دهد. - Process observables:
stdout،stderrو exit status سه observable جدا هستند. stdout برای پیام عادی، stderr برای stream خطا/diagnostic و exit status برای نتیجهای است که process به caller برمیگرداند؛ هیچکدام بهتنهایی file correctness را ثابت نمیکنند. - Filesystem effect: relative path نسبت به execution context تفسیر میشود. بنابراین
output.txtیک identity جهانی نیست. برای اثبات اثر، resolved path و before/after hash یا observation معادل را ثبت کن.
Execution Context Trace از این observables به یک bounded conclusion میرسد. هر چیزی که اندازهگیری نشده، باید unknown بماند؛ inference را بهجای observation جا نزن.
ساخت Execution Context Trace v1
برای هر run حداقل این fields را ثبت کن:
run_idو shell/runtime boundary؛cwdواقعی و resolved executable؛argv؛- environment مرتبطِ whitelistشده، نه dump کامل؛
- stdin اگر در claim مؤثر است؛
stdoutوstderrبهصورت جدا؛- exit status؛
- file pathهای درگیر و hash/observation قبل و بعد؛
- برچسب
OBSERVED / INFERRED / UNKNOWNبرای هر نتیجهٔ مهم؛ - claim فعلی یا probe بعدی؛
- residual uncertainty و تصمیم انسانی.
ترتیب مهم است: اول context را capture کن، بعد آن را تغییر بده. اگر قبل از ثبت cwd یا environment شروع به repair کنی، بخشی از evidence را نابود میکنی و debugging به بازسازی حافظهای تبدیل میشود.
چرا exit 0 و stdout کافی نیستند
در Bash و process model معمول، exit status یک observable از پایان command/process است. این عدد پاسخ میدهد «process چه statusی برگرداند؟»؛ پاسخ نمیدهد «آیا همان فایل یا همان behavior مورد نظر business تغییر کرد؟». ممکن است process کاملاً موفق باشد و روی relative path دیگری کار کرده باشد.
stdout و stderr نیز دو channel جدا هستند. اگر تنها stdout را capture کنی، diagnostic موجود در stderr بخشی از execution evidence نیست. برعکس، وجود warning در stderr هم بهتنهایی failure semantic را ثابت نمیکند؛ باید آن را در کنار exit status و اثر واقعی تفسیر کنی.
PATH و command lookup هم یک boundary دارند. در محیط Bash میتوانی با ابزارهای همان shell مثل command -v یا type evidence جمع کنی، اما claim را به Bash محدود نگه دار. برای process-level evidence، مسیر executableای که runner واقعاً استفاده کرده ارزش بیشتری از حدس براساس نام command دارد.
Relative path دقیقاً جایی است که terminal folklore اغلب شکست میخورد. دو پوشه میتوانند هر دو input.txt و output.txt داشته باشند. همان child program با همان exit status، بسته به cwd، file identity متفاوتی را لمس میکند. تنها راه دفاعپذیر، resolved path و independent file observation است.
مثال کارشده: دو پوشه، یک نام فایل، دو اثر متفاوت
fixture آموزشی دو directory دارد: root و alternate. هر دو input.txt و output.txt دارند اما sentinelهایشان متفاوت است. child program ورودی نسبی را میخواند، DEMO_MODE را از whitelist میگیرد، summary را در stdout مینویسد، diagnostic جدا در stderr میفرستد و روی output.txt همان cwd مینویسد.
Baseline را از root اجرا میکنی. trace باید نشان دهد cwd به root resolve شده، output hash همان فایل root تغییر کرده و فایل alternate ثابت مانده است. حالا همان process-level action را از alternate اجرا کن. exit status باز هم میتواند 0 باشد، ولی hash فایل alternate تغییر میکند. این run مستقیماً claim «exit 0 یعنی فایل مورد انتظار تغییر کرده» را رد میکند.
Mutation دوم DEMO_MODE را از safe به alternate تغییر میدهد. این mutation behavior داخل process را تغییر میدهد ولی file identity را بهتنهایی تعیین نمیکند؛ file identity همچنان از cwd/path resolution میآید. دو متغیر را با یک observation مخلوط نکن.
پنج shortcut گمراهکننده
«فرمان همان است، پس نتیجه باید همان باشد.» repair: context و resolution را ثبت کن؛ command text فقط یکی از ورودیهاست.
«Exit code صفر است، پس task درست است.» repair: intended effect را با oracle مستقل مثل resolved path و file hash بررسی کن.
«stdout چیزی نگفت، پس مشکلی نبود.» repair: stderr را جدا capture کن و نبود evidence را با evidence نبودن یکی نگیر.
«PATH را میدانم؛ همان executable اجرا شده.» repair: executable resolution را در همان محیط مشاهده کن. اگر Bash-specific probe استفاده میکنی، portability boundary را بنویس.
«output.txt همان فایل است.» repair: relative name را identity فرض نکن؛ cwd + resolved path + observation را ثبت کن.
برای مهندس باتجربه: trace را به build/repository practice وصل کن، بدون overlap
در پروژهٔ واقعی ممکن است wrapper script، IDE، task runner، container shell یا CI launcher command را اجرا کند. این درس workspace manager، lockfile، cache یا build-system closure را آموزش نمیدهد؛ آنها متعلق به درسهای بعدیاند. اینجا فقط invariantهای execution-context را نگه دار:
- runner/shell boundary مشخص؛
- cwd و executable resolution قابل بازرسی؛
- argv و environment مرتبط محدود و قابل review؛
- stdout/stderr/exit status جدا؛
- filesystem effect با identity واقعی؛
- observed/inferred/unknown روشن؛
- conclusion محدود به همین evidence.
اگر ابزار سازمانی همین fields را خودکار capture میکند، Execution Context Trace میتواند projection همان data باشد. automation evidence را حذف نمیکند؛ فقط جمعآوری آن را استاندارد میکند.
explicit path، relative path و environment inheritance؛ trade-off بدون حکم جهانی
Absolute یا anchored path ambiguity را کم میکند، اما portability یا relocatability را میتواند محدود کند. استفاده از آن بهتنهایی correctness را ثابت نمیکند.
Relative path برای repository/fixtureهای قابل جابهجایی مفید است، اما معنایش به cwd وابسته است. بنابراین trace باید cwd را همراهش نگه دارد.
Inherited environment راحت است، ولی state پنهان ایجاد میکند. configuration صریحتر قابلیت review را بالا میبرد؛ با این حال هرگز برای debugging کل environment را بدون نیاز dump نکن. فقط keys مرتبط و غیرحساس را capture کن.
Shell-specific inspection میتواند برای diagnosis دقیق همان shell لازم باشد. در کنار آن، process/filesystem observables را نگه دار تا claim portability بیش از منبع رسمی کشیده نشود.
Lab: trace را قبل از repair بساز
در Lab ابتدا fixture را با setup محلی بساز. هیچ network، credential، privilege یا destructive host operation لازم نیست. runner فقط workspaceهای مالکیتدار داخل خود Lab را reset میکند.
برای baseline، case baseline و cwd=root را با DEMO_MODE=safe اجرا کن. stdout، stderr، exit status، resolved executable، cwd و before/after file hashes را در Execution Context Trace ثبت کن. سپس fixture را reset کن و همان probe را با cwd=alternate اجرا کن. اگر exit status 0 ماند ولی file effect عوض شد، آن را بهعنوان evidence counterexample نگه دار.
بعد DEMO_MODE را تغییر بده و مشخص کن کدام observation به environment mutation مربوط است و کدام به cwd. در transfer case نام directoryها و sentinelها عوض شدهاند؛ sequence آمادهای داده نمیشود. قبل از conclusion، یک متغیر را در هر probe isolate کن.
حداقل evidence دفاعپذیر
Execution Context Trace v1 زمانی قابل review است که material conclusionها به observable وصل باشند: shell/runtime boundary، cwd، executable path، argv، selected environment، streams، exit status و file effect. File effect باید با path/hash یا oracle معادل قابل بررسی باشد.
اگر یک field در دسترس نیست، آن را UNKNOWN ثبت کن و claim را کوچکتر کن. اگر بین دو explanation رقابت وجود دارد، کوچکترین probeای را انتخاب کن که آنها را از هم جدا کند. مثال: برای تمایز «mode behavior» و «wrong cwd»، تغییر همزمان هر دو متغیر probe خوبی نیست؛ یکی را ثابت نگه دار.
پذیرش trace یک تصمیم انسانی است. Machine check میتواند schema یا fixture behavior را validate کند، اما نمیتواند residual risk یا scope claim را بهجای learner تعیین کند.
ارزیابی: diagnosis، decision، application و transfer
AS1 — Diagnosis: یک run با exit 0، stdout ظاهراً درست و file effect اشتباه داده میشود. smallest failing boundary و evidence لازم برای رد alternative را مشخص کن.
AS2 — Decision: traceای دریافت میکنی که stdout و exit status دارد اما cwd، stderr و file identity ناقصاند. تصمیم بگیر evidence برای claim ارائهشده کافی است، نیاز به probe دارد یا باید defer شود؛ residual risk را بنویس.
AS3 — Application: Lab baseline و mutation را اجرا و Execution Context Trace v1 را کامل کن. حداقل یک green signal گمراهکننده باید با independent oracle رد شود.
AS4 — Transfer: روی fixture تغییرکرده با cwd و environment متفاوت، روش را بدون command sequence آماده بازسازی کن. نتیجه باید صریحاً بگوید چه چیزی observed است، چه چیزی inferred و چه چیزی هنوز اثبات نشده است.
ابعاد critical غیرقابل جبراناند: context completeness، جداسازی stream/process evidence و filesystem identity proof. پاسخ خوب ولی بدون evidence یکی از این ابعاد، pass کامل نیست.
منبع و مرز freshness
رفتارهای فعلی Bash که در این درس به command search/execution environment، current directory، redirection/streams و exit status مربوطند به مستند رسمی GNU Bash محدود شدهاند. این منبع در research map درس در 2026-09-02 ثبت شده و review_due=2026-10-17 دارد؛ در این authoring claim فنی جدیدی بیرون از همان map اضافه نشده است.
این درس ادعای «همهٔ shellها مثل Bash هستند» ندارد. process/filesystem observationها تا جایی استفاده میشوند که در fixture خودمان قابل مشاهدهاند. symlink normalization، permissions، durability، concurrency، security confinement و host-level isolation بیرون از scope هستند.
Execution Context Trace v1 یک قاعدهٔ طراحی آموزشی برای evidence است، نه استاندارد اجباری یک shell یا سیستمعامل.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
AS1 diagnosis
یک process با exit 0 تمام شده اما hash نشان میدهد فایل همنام در directory دیگری تغییر کرده است. کوچکترین boundary خراب را مشخص کن و evidence لازم برای رد alternative را بنویس.
AS2 decision
Trace فقط stdout و exit status را دارد و cwd، stderr و resolved file identity ثبت نشدهاند. دربارهٔ کفایت evidence تصمیم محدود بده و residual risk را مشخص کن.
AS3 application
Lab baseline و cwd mutation را اجرا و Execution Context Trace v1 را کامل کن. یک green signal گمراهکننده را با oracle مستقل رد کن.
AS4 transfer
روی transfer fixture که directory name، sentinel و DEMO_MODE متفاوت دارد، بدون sequence آماده trace را بازسازی کن و observed/inferred/unknown را جدا کن.
ملاکهای ارزیابی (rubric)
The rubric evaluates evidence quality, not command memorization.
| Dimension | Critical | Sufficient evidence | Blocking failure |
|---|---|---|---|
| Context completeness | Yes | Shell/runtime boundary, cwd, resolved executable, relevant environment and argv are recoverable. | Material context is guessed or omitted. |
| Stream/process separation | Yes | stdout, stderr and exit status are treated as separate observables. | A single green signal is promoted to correctness. |
| Filesystem identity proof | Yes | Resolved path plus before/after hash or equivalent oracle proves the touched file. | Relative filename is treated as identity. |
| Portability boundary | Yes | Bash-specific observations are labeled; process/filesystem claims stay bounded. | Bash semantics are universalized. |
| Bounded conclusion | Yes | Observed/inferred/unknown and residual uncertainty are explicit. | Unknown evidence is invented or hidden. |
| Transfer | No | Method adapts to changed cwd/environment without copying a sequence blindly. | Commands are replayed without re-evaluating the boundary. |
All critical dimensions are non-compensatory. AI may assist with explanation after the evidence question is stated, but the final sufficiency decision remains human.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
مرز ایمنی: فقط فایلهای محلی؛ بدون network، credential، تغییر privilege، حذف host یا dump کامل environment. setup_fixture.py فقط workspaceهای ثابت و ownership-marked داخل همین learner directory را reset میکند.
Baseline
python setup_fixture.py --case baseline- اگر واقعاً در Bash هستی، برای evidence مخصوص همان shell میتوانی
pwd،command -v pythonوtype -a pythonرا ثبت کنی و صریحاً Bash-specific برچسب بزنی. این مراحل از launcher token یعنیpythonاستفاده میکنند؛ اگر عمداً launcher دیگری جایگزین کردی، evidence را برای همان token دقیق ثبت کن. python inspect_workspace.py --case baselinepython run_probe.py --case baseline --cwd root --mode safe- stdout، stderr، exit status، cwd، executable حلشده، environment مرتبط و file hashها را در trace ثبت کن.
- baseline را reset کن و mutation مربوط به cwd را با
alternateاجرا کن. از نام فایل حدس نزن؛ path/hash evidence را ببین. - دوباره reset کن و در حالی که cwd ثابت است
DEMO_MODEرا تغییر بده.
Transfer
با python setup_fixture.py --case transfer case انتقال را بساز. نام directoryها و sentinelها عوض شدهاند. بدون sequence آماده probeها را بازسازی کن و cwd و DEMO_MODE را جدا isolate کن.
تصمیم نهایی انسانی است. exit status سبز فقط status process را نشان میدهد، نه اینکه intended file effect درست بوده است.
رسانه و اسلایدهای درس
فایلهای آموزشی (دانلود)