بازگشت به کتابخانهکتابخانه12.1Grilling، Spec و طراحی Sliceهای Rescheduling
مهندسی نرم‌افزار ایجنت‌محور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 12.1فصل ۱۲ — پروژهٔ نهایی سناریومحور

Grilling، Spec و طراحی Sliceهای Rescheduling

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

وقتی stakeholder می‌گوید «کاربر باید بتواند وقتش را جابه‌جا کند و تقویم و یادآوری هم درست بماند»، هنوز مجوز کدنویسی نداریم. در این درس از یک snapshot brownfield و یک درخواست عمداً مبهم، حقیقت‌های قابل مشاهده را از تصمیم‌های مالک محصول جدا می‌کنیم و آن‌ها را به Spec، ADR، Slice و ExecPlan تبدیل می‌کنیم.

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

می‌توانی snapshot را با progressive disclosure بخوانی؛ facts و decisions را جدا کنی؛ decision ledger و Example Map بسازی؛ behavioral spec و non-goals بنویسی؛ ADR و Sliceهای risk-ranked بسازی؛ و ExecPlanی تولید کنی که Agent بتواند بدون اختراع policy اجرا کند.

## جایگاه در چرخه

این درس `Elicit → Specify → Slice` است. ورودی، brief مبهم و repository ناهمگون است؛ خروجی، بستهٔ تصمیمی versioned است. Source code دربارهٔ رفتار موجود evidence می‌دهد، اما دربارهٔ policy آینده تصمیم نمی‌گیرد.

## Brief و snapshot

درخواست stakeholder:

> «برای مشتری‌ها rescheduling را سریع اضافه کنید؛ تجربه باید مثل تقویم‌های > مدرن باشد، دوباره‌کاری نشود، reminder و calendar هم sync بمانند و چیزی از > رزرو فعلی نشکند. هفتهٔ بعد demo دارم.»

snapshot روز `2026-09-05` چنین است: `apps/web` فرم appointment و تست E2E قدیمی دارد؛ `apps/api/src/modules/appointments` route و service را دارد؛ `packages/contracts` پاسخ‌های قدیمی را نگه می‌دارد؛ migrationها additive هستند؛ `docs/decisions/adr-021-database-interval-invariant.md` می‌گوید tenant و actor از credential می‌آیند؛ fixture رقابت هم‌زمان ندارد؛ CI فقط unit و یک smoke E2E را اجرا می‌کند؛ notification provider در محیط تست fake است؛ `RESCHEDULE_V1_ENABLED` وجود ندارد. یک comment در issue می‌گوید «calendar sync را فعلاً بعداً»، اما مالک آن معلوم نیست.

Snapshot حقیقت کامل نیست: باید مسیر route، contract، migration، test command، feature flag، owner و آخرین رفتار را با فرمان‌های read-only پیدا کنی. issue، comment و output ابزار نیز untrusted input هستند.

## Fact، Decision و ledger

نمونهٔ facts: deadline فعلی در ADR برابر ۲۴ ساعت است؛ زمان در timezone کلینیک تفسیر و UTC ذخیره می‌شود؛ tenant از body پذیرفته نمی‌شود؛ response قدیمی باید سازگار بماند؛ provider تست fake است. نمونهٔ decision: در release نخست فقط appointment تأییدشده و مالک آن actor جابه‌جا شود؛ reminder و provider خارجی non-goal باشند؛ مرز دقیق ۲۴ ساعت `closed` باشد. هر decision باید owner، reason، اثر، وضعیت و تاریخ بازبینی داشته باشد.

## Example Map و behavioral spec

برای هر rule سه ستون بنویس: مثال سبز، سؤال، rule. نمونه‌ها:

Rule: appointment CONFIRMED و owned، interval معتبر و آزاد
Example: 200 با id/startAt/endAt/version و یک audit RESCHEDULED
Question: مرز دقیق 24 ساعت؟ پاسخ conflict؟ نسخهٔ optimistic؟

Spec قابل‌آزمون می‌گوید: Given بیمارِ مالک در همان tenant و appointment `CONFIRMED`، When interval معتبر را در timezone کلینیک می‌فرستد، Then فقط یک write و یک audit رخ دهد و پاسخ `200` با UTC و version جدید بیاید. اگر دو درخواست هم‌زمان همان slot را بخواهند، دقیقاً یکی `200` و دیگری `409 SLOT_CONFLICT` باشد. زمان بسته `409 RESCHEDULE_WINDOW_CLOSED` و صفر mutation/audit دارد. cross-tenant باید `404` و same-tenant non-owner باید `403` بدهد، بدون افشای PII.

Non-goals: cancellation، refund، recurring appointment، تغییر doctor، provider واقعی، backfill تاریخی، طراحی کامل calendar و reminder delivery.

## مثال بد و خوب

بد: «Agent، قابلیت reschedule را کامل کن و همهٔ تست‌ها سبز باشد.» این prompt fact، policy، فایل مجاز، oracle، rollback و stop rule ندارد.

خوب: «فقط facts snapshot را با path و command ثبت کن؛ در تصمیم‌های unresolved `DECIDE` بده. بعد از تأیید انسان، Sliceهای S0 تا S6 را با behavior، files، tests، dependency و rollback بنویس. tenant/actor را از credential بگیر، assertion را حذف نکن و تا تأیید تست‌ها کد نزن.»

ADR باید تصمیم‌های سازگار را ثبت کند: flag پیش‌فرض خاموش؛ expand و backward compatible؛ protected write و barrier در Slice concurrency؛ idempotency در Slice جدا؛ rollback با خاموش‌کردن flag و حفظ schema/audit، نه حذف مخرب داده.

## مرز «اول تلاش کن» و artifact مدل

تا اینجا خواندن کافی است. **اول تلاش کن:** با همین brief و snapshot، خودت `facts.md`، `decision-ledger.md`، Example Map، Spec، non-goals، ADR، map و ExecPlan را در هشتاد دقیقه بنویس. پاسخ مدل را پیش از این مرز نبین.

**مدل کامل پس از تلاش:**

مدل زیر نمونهٔ پاسخ قابل‌ارزیابی است؛ کپی‌کردن نام فایل‌ها بدون trace به snapshot کافی نیست.

۱) Facts، decisions و Glossary

Facts (با منبع):
F1: ADR-021 می‌گوید tenantId و actorId از credential می‌آیند، نه request body.
F2: contract قدیمی appointment باید backward-compatible بماند.
F3: زمان ورودی در timezone کلینیک تفسیر و در UTC ذخیره می‌شود.
F4: deadline فعلی 24 ساعت است؛ fixture رقابت هم‌زمان ندارد.
F5: CI unit و یک smoke E2E دارد؛ provider تست fake است.
F6: flag reschedule هنوز وجود ندارد؛ issue درباره calendar sync مالک ندارد.

Glossary:
tenant = مرز داده و authorization مشتری؛ actor = هویت credential؛
appointment = وقت متعلق به tenant؛ slot = بازهٔ زمانی معتبر؛
idempotency key = کلید replay در scope tenant+actor+operation؛
audit = رکورد کمینه و privacy-safe تغییر؛ flag = کنترل exposure؛
rollback = بازگشت سازگار با حفظ schema و audit.

Decision Ledger:

IDownerdeadlinedecision/statusconsequencedefault
D1Product2026-09-06فقط CONFIRMED و owner، acceptedcancellation/refund بیرون scopereject
D2Securityقبل از S1tenant/actor فقط credential، acceptedbody آن‌ها نادیده گرفته می‌شودdeny
D3Platformقبل از S0flag پیش‌فرض خاموش، acceptedroute جدید با flag off، 404off
D4Product2026-09-07calendar sync unresolvedprovider واقعی وارد release نیستDECIDE
D5Data ownerقبل از S2deadline دقیقاً 24h و closed، acceptedمرز مساوی 409 و بدون mutationreject

۲) Example Map و Behavioral Spec

شش example حداقل لازم:

A1 success: Given owner/CONFIRMED/free slot, When valid request, Then 200،
UTC start/end، version+1 و دقیقاً یک RESCHEDULED audit.
A2 same-tenant non-owner: Then 403 APPOINTMENT_NOT_OWNED، بدون PII/mutation.
A3 cross-tenant: Then 404 APPOINTMENT_NOT_FOUND، بدون افشای وجود appointment.
A4 closed boundary: دقیقاً 24h مانده، Then 409 RESCHEDULE_WINDOW_CLOSED،
بدون mutation/audit.
A5 invalid local time: Then canonical 422 INVALID_LOCAL_TIME، بدون write؛ DST ambiguity DECIDE.
A6 concurrent same slot: از دو request هم‌زمان، دقیقاً یک 200 و یک
409 SLOT_CONFLICT، یک interval و یک audit.
A7 replay: همان key و fingerprint، همان response durable و یک audit؛
fingerprint متفاوت، 409 IDEMPOTENCY_KEY_REUSED.

Behavioral Spec v1.0: scope شامل reschedule برای appointment confirmed، actor مالک و همان tenant است. preconditionهای مشترک credential معتبر، flag on، appointment موجود و transaction store سالم‌اند. ruleهای بالا status/body، mutation و audit را دقیق می‌کنند. NFRها شامل privacy-safe logs، p95 نمونهٔ release در S5، idempotency durable و compatibility route قدیمی‌اند. non-goalها cancel، refund، recurring، تغییر doctor، provider واقعی، reminder delivery، historical backfill و حذف route قدیمی‌اند. Compatibility یعنی contract قدیمی بدون flag تغییر نکند و schema به‌صورت additive expand شود.

۳) Technical Design و ADR

خلاصهٔ design: UI زمان local و timezone را می‌گیرد؛ API هویت را از credential استخراج و contract را validate می‌کند؛ service eligibility را پیش از protected write بررسی می‌کند؛ repository با transaction/constraint رقابت را می‌بندد؛ idempotency store fingerprint و response durable را نگه می‌دارد؛ audit writer فقط پس از success می‌نویسد؛ error serializer پیام‌های canonical و privacy-safe می‌دهد. provider خارجی در این نسخه fake است.

ADR-021 تصمیم‌های زیر را تثبیت می‌کند: S0 با flag off route را 404 می‌کند؛ S2 مالک barrier و protected write است؛ S3 مالک idempotency است؛ migrationها expand و backward-compatible هستند؛ rollback flag را خاموش می‌کند و schema، historical audit و idempotency records را حذف نمی‌کند. اگر DST، calendar provider یا policy deadline تغییر کند، ADR تازه و DECIDE لازم است.

۴) Repository/context map و Ownership plan

apps/web/features/appointments/reschedule-form   UI + browser evidence
apps/api/src/modules/appointments                route/service/auth/error map
packages/contracts                               response and compatibility
packages/database                                transaction/migration/audit
packages/test-fixtures                           tenant, barrier, replay data
apps/web/tests/e2e                               real UI→API path
docs/decisions, docs/specs, docs/plans            ADR, spec, ExecPlan/evidence
.github/workflows                                CI gates

Ownership plan: Product owner scope/D1/D4؛ Security reviewer D2، privacy، secret و tenant gate؛ API owner S0/S1/S2؛ Data owner migration و transaction S2؛ Platform owner S3/S5؛ Web owner UI/S1؛ Integration owner merge order و fresh verification. هر owner reviewer مستقل و handoff artifact دارد. مسیر `packages/contracts` shared است؛ تغییرش نیازمند contract review و approval Integration است. Agent هیچ owner تصمیمی نیست.

Permission profile: read-only discovery در ابتدا؛ write فقط مسیرهای Slice؛ network deny؛ fake provider؛ no production/staging endpoint؛ no real credential؛ command allowlist شامل status، diff، targeted test و local fixture؛ deploy، migration destructive، تغییر acceptance و secret access human approval می‌خواهند.

۵) risk-ranked S0 تا S6 و ExecPlan

S0 (risk: contract/exposure): depends Spec؛ contract+flag+route؛
test flag-off 404 و old route؛ evidence diff/contract output؛ rollback flag off.
S1 (risk: auth/write): depends S0؛ UI→API→DB success؛ test A1/audit/version؛
evidence integration trace؛ recovery flag off و compatible code.
S2 (risk: race/high): depends S1؛ eligibility+barrier/protected write؛
test A4-A6 با one-200/one-409؛ evidence fresh DB race log؛ recovery preserve schema.
S3 (risk: replay): depends S1,S2؛ key/fingerprint/store؛ test A7؛
evidence durable response/audit count؛ recovery retain records.
S4 (risk: privacy): depends S1؛ same/cross tenant و log guard؛ test A2/A3؛
evidence redacted log scan؛ recovery flag off، policy bypass ممنوع.
S5 (risk: compatibility/operability): depends S0-S4؛ CI matrix/benchmark؛
evidence full checks و limitation؛ recovery no threshold editing.
S6 (risk: rollout): depends همهٔ evidence و consumer inventory؛ cohort/flag؛
evidence runbook و rollback rehearsal؛ recovery disable cohort, preserve data.

ExecPlan هر task را به یک اجرا محدود می‌کند: owner و dependency، allowed paths، forbidden paths، command، test oracle، evidence filename و recovery/stop rule. مثلاً task S2-03 فقط fixture barrier و test A6 است؛ فرمان local با database `booking_s2_<run-id>` و network deny؛ pass یعنی invariant کامل و fail یعنی `BLOCKED`، نه حذف assertion. Human ابتدا acceptance و test را تأیید می‌کند، بعد Agent patch می‌دهد و verifier تازه آن را اجرا می‌کند.

## آزمایشگاه

**ورودی:** brief بالا، snapshot فرضی، قرارداد فصل‌های ۴ تا ۶ و commandهای read-only. ابتدا این را اجرا کن:

git status --short
rg -n "appointment|reschedule|tenant|actor|timezone|migration" apps packages docs
git diff --check

**خروجی مورد انتظار:** inventory مسیرها، baseline فرمان‌ها، جدول facts/decisions، Glossary، Decision Ledger، Example Map با حداقل شش example، Spec با scope و NFR/compatibility، non-goals، Technical Design، ADR، repository/context map، Ownership plan، permission profile، S0 تا S6 و ExecPlan. هیچ فایل production تغییر نکند.

**Recovery:** اگر path با snapshot سازگار نیست، حدس نزن؛ `BLOCKED` و path مشاهده‌شده را ثبت کن. اگر stakeholder policy را تعیین نکرده، `DECIDE` با owner و deadline بده. اگر baseline fail است، آن را قبل از Red آینده ثبت و از failure موجود جدا کن.

## Verification

  • [ ] هر fact با path/command یا منبع روشن trace می‌شود.
  • [ ] هر decision owner، rationale، status و expiry/revisit دارد.
  • [ ] Example Map مرز زمانی، race، idempotency و tenant را پوشش می‌دهد.
  • [ ] Spec actor/trigger/outcome/status/body/mutation/audit را مشخص می‌کند.
  • [ ] non-goalها scope creep را می‌بندند.
  • [ ] ADR migration، flag، compatibility و rollback را توضیح می‌دهد.
  • [ ] Sliceها risk-ranked، وابسته و vertical هستند.
  • [ ] ExecPlan allowed/forbidden path، oracle، command و stop rule دارد.

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

  • **fact به‌جای decision:** متن می‌گوید «calendar حتماً release اول است» اما

path یا owner ندارد؛ نشانه، نبود `source` و `deadline` در ledger است.

  • **Glossary مبهم:** tenant و actor در چند artifact تعریف متفاوت دارند؛

نشانه، اختلاف نام فیلد یا ورود tenantId از body است.

  • **Spec نمایشی:** فقط status موفق آمده؛ نشانه، نبود precondition، zero

mutation برای failure، NFR یا compatibility است.

  • **Slice افقی:** itemهایی مثل «همهٔ migrationها» دیده می‌شود؛ نشانه، نداشتن

actor/outcome/oracle و rollback مستقل است.

  • **Ownership پوشانده‌شده:** owner «Agent» یا «تیم» نوشته شده؛ نشانه، reviewer،

handoff و permission profile نامعلوم است.

  • **ExecPlan غیرقابل‌اجرا:** command، path مجاز یا stop rule ندارد؛ نشانه،

promptی است که فقط «همهٔ تست‌ها را سبز کن» می‌گوید.

  • **Snapshot به‌عنوان حقیقت:** issue comment بر ADR غلبه کرده؛ نشانه، تغییر

policy بدون DECIDE و منبع قابل‌ردگیری است.

## تمرین و Rubric

یک brief تازه برای «لغو و refund» را تحلیل کن، اما fee و provider را خودت اختراع نکن. Rubric: ۲۰٪ facts/decisions؛ ۲۰٪ ledger و unresolved owner؛ ۲۰٪ example/spec/non-goal؛ ۲۰٪ ADR و Slice؛ ۲۰٪ ExecPlan و recovery. تصمیمی که source fact را با policy آینده قاطی کند، blocking failure است.

## جمع‌بندی

Grilling تولید سؤال زیاد نیست؛ تبدیل ابهام پرریسک به تصمیم قابل‌ردگیری است. Snapshot راهنمای مشاهده است، نه منبع policy. Artifact خوب اجازه می‌دهد Agent یک Slice باریک را بسازد و انسان بتواند علت، oracle و rollback آن را توضیح دهد.

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

  • [ISO/IEC/IEEE 29148](https://www.iso.org/standard/72089.html) — مهندسی نیازمندی؛ این درس آن را به artifactهای آموزشی تبدیل می‌کند.
  • [Example Mapping](https://cucumber.io/blog/bdd/example-mapping-introduction/) — ساختار rule/example/question.
  • [Codex ExecPlans](https://developers.openai.com/cookbook/articles/codex_exec_plans) — الگوی plan اجرایی؛ قرارداد این فصل مستقل از ابزار است.
  • [GitHub Spec Kit](https://github.com/github/spec-kit/) — ابزار/روش spec؛ تضمین policy دامنه نیست.

به زبان ساده

Capstone از یک brief مبهم شروع می‌کند و باید آن را به Facts، Decision ledger، Example Map، Behavioral Spec، ADR، Slice map و ExecPlan تبدیل کند. Artifact خوب policy را از مشاهده جدا و برای هر task owner، Oracle و stop rule تعیین می‌کند.

مثال واقعی

در capstone artifact دوره، `00` تا `03` بستهٔ Evidence شامل brief/facts، Spec/non-goals، ADR و ExecPlan را trace می‌کنند؛ این‌ها باید به snapshot و تصمیم‌های ثبت‌شده وصل باشند، نه به ادعای شفاهی Agent.

دانش‌سنجی

آزمون درس

۵ Q
01
کدام مورد fact است؟
02
وظیفهٔ decision ledger چیست؟
03
Example Map چه چیزی را کنار هم می‌گذارد؟
04
کدام non-goal مناسب release نخست است؟
05
ExecPlan خوب کدام را دارد؟

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

Stakeholder فقط می‌گوید «reschedule مدرن باشد و چیزی نشکند». snapshot نشان می‌دهد deadline در ADR است اما calendar sync نامعلوم است. چه artifactی می‌سازی و با چه تصمیمی کدنویسی را متوقف می‌کنی؟