بازگشت به کتابخانهکتابخانه9.3Ralph امن و محدود: بودجه، Sandbox و خروجی روشن
مهندسی نرم‌افزار ایجنت‌محورAGENTIC SOFTWARE ENGINEERING — از Grilling و Context Engineering تا TDD، Ralph، Subagent، امنیت و تحویل قابل‌اعتماد
v1.0.0
01واقعیت مهندسی ایجنت‌محور
02Grilling و زبان مشترک
03Context Engineering
04Spec-Driven Development و برنامهٔ اجرایی
05Vertical Slices و تحویل تدریجی
06TDD با ایجنت‌ها
07گردش‌کار روزانه، Debug و UI Prototyping
08ساخت هارنس — Rules، Skills، Hooks و MCP
09Ralph و اجرای طولانی‌مدت
10Subagent، Worktree و ارکستراسیون موازی
11Verification، Security و مقیاس تیمی
12پروژهٔ نهایی سناریومحور
LESSON 9.3فصل ۹ — Ralph و اجرای طولانی‌مدت

Ralph امن و محدود: بودجه، Sandbox و خروجی روشن

  • ~۷۲ دقیقه
  • ۵ پرسش
  • متن را انتخاب کن تا هایلایت شود

یک loop unattended فقط وقتی آزمایشگاهی و قابل‌قبول است که سقف داشته باشد. در این درس loop را به ماشین حالت تبدیل می‌کنیم: orient، select، implement، verify، commit و سپس `COMPLETE`، `BLOCKED` یا `DECIDE`. حداکثر هشت iteration، wall-clock و spend budget، sandbox و allowlist فرمان، جای اعتماد به «مدل خودش مراقب است» را می‌گیرند.

## اهداف یادگیری

پس از درس می‌توانی ماشین حالت Ralph را توضیح دهی؛ سقف هشت iteration و بودجهٔ زمان/هزینه تعریف کنی؛ loop را در sandbox با command allowlist اجرا کنی؛ production credential را حذف کنی؛ verification مستقل طراحی کنی؛ و crash/restart را بدون تکرار mutation یا از دست رفتن evidence بازیابی کنی.

## جایگاه در چرخهٔ سرتاسری

این درس کنترل اجرای درس‌های ۳۲ و ۳۳ است. پیش از loop باید Spec، acceptance immutable، تست protected، task graph، permission profile و recovery موجود باشد. Ralph فقط کار bounded را اجرا می‌کند؛ تصمیم محصول، تغییر acceptance، deploy و merge production بیرون اختیار آن است.

این ترتیب عمداً هزینهٔ آماده‌سازی دارد: loop کوتاه‌تر از بازبینی، اما بدون قرارداد فقط سرعت تولید خطای تکرارشونده است. هر checkpoint باید به artifact قابل‌خواندن انسان اشاره کند.

ماشین حالت Ralph محدود

*شکل: loop از orientation تا commit می‌رود و با بودجهٔ سخت به `COMPLETE`، `BLOCKED` یا `DECIDE` خارج می‌شود؛ متن جایگزین: ماشین حالت اجرای یک story با verification مستقل و توقف زمان/هزینه/تکرار.*

## ماشین حالت و خروجی‌ها

`ORIENT` state و محیط را می‌خواند؛ `SELECT` فقط یک task آماده را انتخاب می‌کند؛ `IMPLEMENT` patch محدود می‌سازد؛ `VERIFY` تست و diff را می‌سنجد؛ `COMMIT` evidence را ثبت می‌کند. اگر acceptance و همهٔ کنترل‌ها pass شد `COMPLETE` است. نبود dependency، crash تکرارشونده، command خارج allowlist یا budget تمام‌شده `BLOCKED` است. تناقض policy، acceptance یا migration که انسان باید انتخاب کند `DECIDE` است. «مدل متوقف شد» هیچ‌کدام از این خروجی‌ها نیست.

مثال بد

while true; do
  agent --approve-all --env production
  git add . && git commit -m auto
done

این فرمان عمداً به‌عنوان الگوی ناامن فقط تحلیل می‌شود و نباید اجرا شود: loop نامحدود، approval کلی، credential production، stage کردن فایل‌های ناشناخته و نبود verifier دارد.

مثال خوب: قرارداد امن

max_iterations: 8
wall_clock: 20m
spend_budget: EXAMPLE_BUDGET_DO_NOT_CHARGE
workspace: disposable ./lab-workspace
network: deny
commands: git status, git diff --check, npm test -- --runInBand
credentials: none; no production endpoint
verification: fresh process + protected tests + human review
exits: COMPLETE | BLOCKED | DECIDE

هزینهٔ نمونه را به مقدار نمادین محدود می‌کنیم؛ هیچ کلید یا حساب واقعی در Lab نیست. `commands` باید parser/allowlist داشته باشد، نه صرفاً جست‌وجوی substring؛ مسیرها، argumentها و working directory نیز validate می‌شوند.

## budget و safety

بودجهٔ wall-clock جلوی hang را می‌گیرد؛ iteration سقف retry و context churn است؛ spend budget جلوی هزینهٔ پیش‌بینی‌نشده را می‌گیرد؛ command budget و حجم output جلوی abuse را کم می‌کنند. این‌ها correctness را ثابت نمی‌کنند. timeout باید process و child process را متوقف کند و state آخر را flush کند. پس از budget exit، loop اجازهٔ «یک دور آخر» ندارد.

Sandbox باید workspace disposable، user کم‌امتیاز، home/SSH/keychain خارج، network deny-by-default و database fixture ephemeral داشته باشد. production credential، staging write، cloud token و endpoint واقعی ممنوع‌اند. حتی اگر secret لازم به نظر برسد، Lab با fake adapter و `EXAMPLE_TOKEN_DO_NOT_USE` کار می‌کند؛ این مقدار credential نیست.

## independent verification

Agentی که patch را نوشته نباید تنها داور completion باشد. verifier تازه باید state و acceptance immutable را بخواند، diff و status را بازبینی کند، test هدفمند و سپس checks لازم را اجرا کند و خروجی را در evidence ثبت کند. `COMPLETE` یعنی همهٔ gateهای قرارداد pass شده، نه فقط process exit code صفر. اگر verifier نتواند setup را reproduce کند، خروجی `BLOCKED` است.

## سناریوی booking-platform

loop روی S2 concurrency در database محلی ephemeral کار می‌کند. allowlist فقط `vitest` برای تست race، `git diff --check` و خواندن `tasks.json`/Spec است. هر درخواست migration، network، تغییر acceptance، دسترسی به staging یا ارسال notification باید `DECIDE` بدهد. verifier مستقل یک fixture تازه می‌سازد و invariant «دقیقاً یک `200`، یک `409 SLOT_CONFLICT`، یک audit در success و zero mutation/audit در failure» را بررسی می‌کند.

## crash/restart recovery

قبل از هر iteration، `state.json` با `runId`, `taskId`, `iteration`, `startedAt`, `lastCommit`, `budgetRemaining` و `phase` به‌صورت atomic نوشته می‌شود. بعد از patch، diff و خروجی test به artifact محلی می‌رود؛ commit فقط پس از pass verification انجام می‌شود. اگر process وسط کار crash کرد، session تازه `git status` و state را می‌خواند: diff uncommitted را بررسی و یا به checkpoint امن برمی‌گرداند، اما هرگز کورکورانه دوباره mutation را اجرا نمی‌کند. اگر commit وجود دارد، test را دوباره verify می‌کند و task را دوباره claim نمی‌کند. state ناقص یا چند commit متناقض یعنی `BLOCKED`.

## آزمایشگاه گام‌به‌گام

**ورودی:** fixture booking، یک task S2، تست protected و فایل policy بالا. ۱. workspace یک‌بارمصرف و fake database بساز. ۲. allowlist را با فرمان‌های بدون شبکه تنظیم کن. ۳. loop را با stub Agent و `max_iterations=8` اجرا کن. ۴. در iteration دوم process را terminate کن. ۵. session تازه را اجرا و recovery را ثبت کن. ۶. verifier مستقل را در process جدا اجرا کن.

**خروجی مورد انتظار:** log فاز، iteration، زمان باقی‌مانده، commit و test output؛ پایان یکی از سه signal دقیق. **Recovery:** crash با checkpoint و diff بررسی می‌شود؛ timeout با flush و `BLOCKED`؛ تناقض policy با `DECIDE`; test failure پس از سقف retry با `BLOCKED`. هیچ مسیر recovery به production یا credential واقعی وصل نیست.

## خطاهای رایج و نشانه‌ها

  • سقف iteration هشت است اما retry داخلی ابزار نامحدود می‌ماند.
  • timeout فقط parent را می‌کشد و child process ادامه می‌دهد.
  • allowlist نام command را بررسی می‌کند اما argument/path را نه.
  • Agent acceptance یا test را برای completion تغییر می‌دهد.
  • verifier همان context و همان فرض‌های implementer را دارد.
  • crash باعث اجرای دوبارهٔ migration یا duplicate audit می‌شود.

## Verification

  • [ ] ارجاع تصویر، alt و caption حاضر و درست است.
  • [ ] loop حداکثر هشت iteration، timeout و spend budget دارد.
  • [ ] sandbox، network deny و command allowlist واقعی/محدود هستند.
  • [ ] production credential و endpoint در Lab وجود ندارد.
  • [ ] verifier مستقل acceptance، diff و test را اجرا می‌کند.
  • [ ] فقط `COMPLETE`، `BLOCKED` یا `DECIDE` خروجی نهایی‌اند.
  • [ ] crash/restart با checkpoint، atomic state و بدون mutation کور recover می‌شود.

## تمرین و Rubric

یک loop نامحدود را که تست را تغییر می‌دهد و به staging token دسترسی دارد، بازطراحی کن.

**Rubric:** حداکثر ۸ iteration، wall-clock و spend budget؛ sandbox disposable و network deny؛ allowlist همراه argument؛ حذف credential production؛ acceptance immutable و verifier مستقل؛ سه خروجی صریح؛ و recovery برای crash، timeout، failure و policy ambiguity داشته باشد. صرفاً افزودن «کاربر تأیید کند» کافی نیست.

## جمع‌بندی

Ralph امن یعنی loopی که بتوان آن را متوقف، بازسازی و ممیزی کرد. state machine، budget، sandbox، allowlist، credential hygiene و verification مستقل با هم کار می‌کنند. هر ambiguity یا شکست تکرارشونده باید به انسان بازگردد، نه اینکه با retry پنهان شود.

## منابع مستقیم

  • [Ralph state pattern — Geoffrey Huntley](https://ghuntley.com/ralph/) — منبع جامعه‌محور pattern؛ محدودیت‌های امنیتی این درس کنترل آموزشی‌اند.
  • [Anthropic — Effective harnesses for long-running agents](https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents) — گزارش میدانی دربارهٔ state و handoff؛ ضمانت safety نیست.
  • [OpenAI Codex sandboxing](https://developers.openai.com/codex/sandboxing) — مستند رسمی دربارهٔ sandbox و permission؛ profile محصولی را باید با محیط خود تطبیق داد.
  • [NIST SSDF](https://csrc.nist.gov/pubs/sp/800/218/final) — چارچوب رسمی کنترل‌های توسعهٔ امن؛ Ralph-specific نیست.
  • [Anthropic Claude Plugins Official — Ralph Loop](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/ralph-loop) — منبع رسمی کد/مستندات plugin برای Claude Code؛ سطح شواهد «مستندات و پیاده‌سازی رسمی محصول»، نه پژوهش مستقل دربارهٔ کیفیت یا ROI. گزینهٔ `--max-iterations` در plugin مستند شده، اما این درس سقف سخت هشت iteration و کنترل‌های sandbox، spend و verification مستقل را به‌عنوان قرارداد آموزشی اضافه می‌کند.

به زبان ساده

Ralph محدود یک ماشین حالت است: orient، select، implement، verify و commit، سپس خروجی صریح. سقف iteration و زمان، sandbox، allowlist و verifier مستقل جلوی retry بی‌پایان و success کاذب را می‌گیرند.

مثال واقعی

در اجرای فرضی S2، حداکثر هشت iteration روی database محلی ephemeral مجاز است؛ crash با خواندن `state.json` و Diff بازیابی می‌شود، نه با اجرای کور دوبارهٔ mutation.

دانش‌سنجی

آزمون درس

۵ Q
01
حداکثر iteration در قرارداد این درس چقدر است؟
02
کدام خروجی برای ابهام policy مناسب است؟
03
independent verification یعنی چه؟
04
کدام مورد در sandbox آزمایشگاهی مجاز نیست؟
05
پس از crash وسط mutation چه می‌کنی؟

سناریوی تشریحی

یک loop نامحدود با test mutation، staging token و retry داخلی را به قرارداد امن تبدیل کن.