بازگشت به کتابخانهکتابخانه4.1Spec-first، Spec-anchored و Spec-as-source
مهندسی نرم‌افزار ایجنت‌محور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 4.1فصل ۴ — Spec-Driven Development و برنامهٔ اجرایی

Spec-first، Spec-anchored و Spec-as-source

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

تیم booking-platform گفته است «reschedule را با SDD بسازید». یک نفر فوراً template ابزار را اجرا می‌کند، دیگری یک سند کامل می‌نویسد و نفر سوم می‌گوید فقط تست‌ها کافی‌اند. هر سه ممکن است کار مفیدی کنند، اما یک عبارت مشترک برای سه قرارداد متفاوت کافی نیست. SDD نام یک استاندارد واحد یا تضمین کیفیت نیست؛ نام خانواده‌ای از گردش‌کارهاست که Spec را جدی‌تر از توضیح شفاهی می‌گیرند. پیش از اجرای Agent باید روشن کنیم Spec در این تغییر چه authority دارد، چه چیز از آن تولید می‌شود و کجا انسان هنوز تصمیم می‌گیرد.

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

پس از این درس می‌توانی تفاوت spec-first، spec-anchored و spec-as-source را با اثر عملی‌شان توضیح دهی، اصطلاح ناپایدار SDD را دقیق و بدون ادعای استاندارد به کار ببری، جریان Spec Kit یعنی `Spec → Plan → Tasks → Implement` را به‌عنوان یک نمونهٔ ابزار معرفی کنی، و برای reschedule سطح مناسب authority را انتخاب کنی.

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

فصل ۲ مسئله، Decision ledger و Acceptance example را ساخت و فصل ۳ مسیرهای مخزن، دستورها و حافظهٔ پایدار را به Context قابل بازیابی تبدیل کرد. این درس در گذار Elicit → Specify قرار دارد: تعیین می‌کند artifact رفتاری چه نقشی در Plan، Task و پیاده‌سازی دارد. درس ۱۳ خود Behavioral Spec را می‌نویسد؛ هنوز API، schema یا migration را انتخاب نمی‌کنیم.

## SDD یک واژهٔ حل‌نشده است

در منابع ابزارها، «spec-driven development» گاهی به نوشتن سند پیش از code، گاهی به تولید task و code از artifactهای زنده، و گاهی به نگه‌داشتن requirement به‌عنوان مرجع بازبینی گفته می‌شود. تحلیل Martin Fowler از ابزارهایی مانند Kiro، Spec Kit و Tessl نیز همین تنوع را برجسته می‌کند. پس جملهٔ «ما SDD داریم» فاقد اطلاعات عملی است؛ باید بگوییم کدام artifact، برای کدام Scope، چه status و چه مسیر تغییر دارد.

این عدم‌قطعیت عیب لغت نیست؛ هشدار مهندسی است. Spec می‌تواند قدیمی، ناقص یا حاصل policy حل‌نشده باشد. Agent ممکن است از متنی منظم، implementation نامنظم تولید کند. برعکس، کد خوب هم نمی‌تواند هدف کسب‌وکار یا قانون refund را از خودش کشف کند. بنابراین Spec authority تصمیم‌های پذیرفته‌شده و رفتار توافق‌شده است، نه مجوز حذف review، test یا owner.

سه سطح را با سؤال authority جدا کنید

**Spec-first (مشخصات‌نخست)** می‌پرسد: «پیش از پیاده‌سازی، چه چیزی باید روشن شود؟» تیم Scope، non-goal، Rule و مثال را ابتدا می‌نویسد و سپس design/code را می‌سازد. رابطه عمدتاً زمانی است، نه ماشینی. یک تغییر کوچک copy هم می‌تواند spec-first باشد اگر policy را عوض می‌کند؛ لازم نیست generator داشته باشد.

**Spec-anchored (لنگرشده به مشخصات)** می‌پرسد: «هنگام اختلاف، چه artifactی مرجع بازبینی است؟» Spec همراه code می‌ماند و PR باید نشان دهد test، design و تغییر با آن سازگارند. Task ممکن است دستی نوشته شود و implementation آزاد باشد، ولی هر divergence باید یا bug باشد یا تغییر آگاهانهٔ Spec با owner. این سطح برای Brownfield معمولاً واقع‌بینانه‌تر است: code قدیمی کامل از Spec تولید نشده، اما تغییر جدید به رفتار توافق‌شده لنگر دارد.

**Spec-as-source (مشخصات به‌مثابهٔ منبع)** می‌پرسد: «آیا specification نگه‌داری‌شده، منبع اصلی تولید implementation است؟» در این رویکرد code و artifactهای اجرایی از Spec canonical تولید می‌شوند و pipeline یا کنترل مکانیکی، drift میان آن‌ها را تشخیص می‌دهد یا مانع می‌شود. generator، grammar/schema، versioning و بازتولید باید معلوم باشند. خواندن markdown توسط Agent، یا استخراج انسانی task و contract از آن، spec-as-source نیست.

هر سه می‌توانند هم‌زمان حضور داشته باشند، اما نباید نامشان را کش بدهیم. برای reschedule، ابتدا behavioral spec را پیش از code می‌نویسیم؛ همان سند مرجع PR می‌شود؛ سپس انسان task graph را از آن تهیه و بازبینی می‌کند. این دو spec-first و spec-anchored هستند، نه spec-as-source. فقط اگر تیم یک schema اجرایی دارد که route/client/test را تولید و در CI drift را رد می‌کند، می‌تواند همان بخش را spec-as-source بنامد.

## جریان نمونهٔ Spec Kit

Spec Kit یک ابزار/قالب محصولی است، نه تعریف علمی SDD. گردش شناخته‌شدهٔ آن Spec سپس Plan، Tasks و Implement است. ارزش زنجیره در نام commandها نیست؛ هر پیکان باید artifact ورودی، خروجی و gate داشته باشد:

Acceptance examples + ledger
        ↓  (policy و scope پذیرفته)
Behavioral Spec
        ↓  (design قابل بازبینی)
Technical design / ADR
        ↓  (dependency و evidence روشن)
ExecPlan + task graph
        ↓  (task کوچک با verify)
Implementation → test/evidence → Spec review
زنجیرهٔ Spec تا Evidence

*نمودار، پیکان یک‌طرفهٔ تولید کد نیست؛ evidence و بازبینی می‌توانند Spec یا Plan را با authority مناسب به‌روزرسانی کنند.*

در مرحلهٔ Spec، Agent می‌تواند مثال‌های فصل ۲، glossary و ledger را جمع و ابهام‌ها را `DECIDE` کند. در Plan، repository map فصل ۳ اجازه می‌دهد مسیر واقعی route، contract و test نوشته شود. Tasks باید وابستگی، مالکیت و فرمان verification داشته باشند. Implement فقط یک task تأییدشده را برمی‌دارد و نتیجه را به evidence وصل می‌کند. اگر test رفتار جدید خلاف Spec را نشان دهد، Agent نباید silent Spec را تغییر دهد: یا defect implementation است، یا تغییر رفتار نیازمند owner و revision artifact است.

## Spec چه چیزی نیست؟

Spec قرارداد API به‌تنهایی نیست: رفتار کاربر، authorization، non-goal و نتیجهٔ خطا را هم دارد. Spec جای ADR نیست: ADR یک trade-off معماری پذیرفته مانند مرجع timezone یا exclusion constraint را ثبت می‌کند. Spec جای ExecPlan هم نیست: «از reschedule پشتیبانی شود» گام، path، dependency و evidence ندارد. و Spec test suite نیست: testها نمونه‌های اجرایی‌اند، اما ممکن است فقط مسیر خوش‌بینانه را پوشش دهند یا Oracle ضعیف داشته باشند.

این تفکیک از تکثیر جلوگیری می‌کند. Behavioral Spec می‌گوید درخواست تکراری نباید دو اثر بسازد؛ technical design می‌گوید key کجا ذخیره و response چگونه بازپخش می‌شود؛ ExecPlan می‌گوید چه migration، test concurrent و فرمانی لازم است. یک تغییر policy ابتدا به Spec/ledger برمی‌گردد و سپس مشتق‌ها بازنگری می‌شوند.

## مثال واقعی: انتخاب سطح برای reschedule

فرض کنید Decision ledger می‌گوید timezone کلینیک authority است، adjacent slot مجاز است و refund خارج از Scope. تیم این مرز را در Spec ثبت می‌کند؛ این spec-first است. در PR، reviewer سناریوی DST، مالکیت Tenant و conflict را با همان متن چک می‌کند؛ این spec-anchored است. سپس Agent taskهای «contract»، «transaction»، «integration test» و «E2E» را پیشنهاد می‌دهد و انسان بازبینی می‌کند؛ این derivation انسانی است، نه spec-as-source.

اگر در Brownfield واقعاً spec-as-source می‌سازید، scope آن را کوچک و mechanical نگه دارید: مثلاً OpenAPI/JSON Schema canonical که client را تولید می‌کند و CI تفاوت generated output را رد می‌کند. routeهای موجود، naming و migration policy از repository map کشف می‌شوند، نه از خیال template. source بودن، نیاز به provenance و reproducibility را بیشتر می‌کند، نه کمتر.

مثال ضعیف و علت شکست

یک Spec برای reschedule بساز و همهٔ فایل‌ها را طبق آن تولید کن.

این prompt هدف، Scope، authority و stop condition ندارد. معلوم نیست cancellation یا refund شامل است، «همهٔ فایل‌ها» کجاست، و آیا Agent حق دارد policy adjacent slot را حدس بزند. ظاهر قطعی دستور، واژهٔ SDD را به پوشش automation بی‌حد تبدیل می‌کند.

مثال اصلاح‌شده

هدف: reschedule امن در یک Tenant.
Authority: Behavioral Spec v0.1 مرجع رفتار است؛ ledger برای adjacent slots هنوز DECIDE است.
Non-goal: refund، reschedule سریالی و migration تاریخی.
روش: spec-first و spec-anchored؛ task graph پیشنهادی انسان‌بازبینی‌شده است.
خروجی: سؤال‌های باز، Spec پیشنهادی و trace هر task به section؛ بدون تغییر code یا ادعای generation.
Stop: بدون پاسخ owner برای policy مسدودکننده، BLOCKED ثبت کن.

این prompt به Agent اجازهٔ کشف و ساخت پیش‌نویس می‌دهد، اما authority یا generation مکانیکی را جعل نمی‌کند. اگر generated code در Scope بود، prompt باید schema canonical، generator، نسخهٔ آن و gate تشخیص drift را جدا نام ببرد.

## آزمایشگاه: قرارداد SDD تغییر را بنویس

**ورودی:** acceptance exampleهای reschedule، glossary، Decision ledger و repository map فصل‌های ۲ و ۳. **گام‌ها:** ۱) سه جمله بنویس که نام سطح SDD، artifact canonical و authority هر کدام را بگوید. ۲) یک زنجیرهٔ Spec → Plan → Tasks → Implement با gate کنار هر پیکان بساز. ۳) برای timezone، adjacent slot و refund تعیین کن چه چیزی accepted، `DECIDE` و خارج از Scope است. ۴) یک prompt اصلاح‌شده با stop condition بنویس. ۵) taskهای مشتق‌شده را با بخش Spec trace کن، نه با حدس Agent.

**فرمان read-only پیشنهادی:**

rg -n "timezone|adjacent|refund|reschedule" docs/specs docs/decisions apps packages

**خروجی مورد انتظار:** اگر مسیرها وجود داشته باشند، فرمان path و شمارهٔ خط candidateها را می‌دهد؛ نبود خروجی، policy جدید یا نبود مخزن واقعی را ثابت نمی‌کند و باید limitation ثبت شود. Artifact نهایی یک قرارداد کوتاه دارد که می‌گوید Spec مرجع بازبینی است، چه چیز تولید/مشتق می‌شود و چه تصمیمی مانع اجراست.

**Recovery:** اگر search بسیار گسترده است، آن را به pathهای map محدود کن. اگر Spec و test موجود اختلاف دارند، یکی را بی‌صدا «منبع حقیقت» ننام؛ provenance، owner و impact را ثبت و `DECIDE` کن. اگر tool template مرحله‌ای دیگر دارد، مفاهیم artifact/gate را حفظ کن و نام command را نسخه‌دار نگه دار.

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

  • **واژه بدون قرارداد:** «SDD» نوشته شده ولی artifact و authority معلوم نیست.
  • **Spec مقدس:** تغییر رفتار واقعی با وجود evidence به‌روزرسانی نمی‌شود.
  • **تولیدکنندهٔ خیالی:** prose را source مولد می‌نامند، ولی generator و مسیر بازتولید ندارند.
  • **کد جای policy:** Agent از route یا test قدیمی deadline/refund را تصمیم محصول نتیجه می‌گیرد.
  • **زنجیرهٔ بی‌بازخورد:** Plan ساخته می‌شود ولی failure test به Spec یا ledger برنمی‌گردد.

## چک‌لیست Verification

  • [ ] سطح SDD و معنای عملی آن را نام برده‌ام.
  • [ ] Spec، ADR، Plan و test را از نظر نقش جدا کرده‌ام.
  • [ ] source/mشتق‌شدن، generator یا review gate مشخص دارد.
  • [ ] هر policy باز owner و `DECIDE/BLOCKED` دارد.
  • [ ] taskها به بخش Spec و evidence قابل‌راستی‌آزمایی trace می‌شوند.
  • [ ] نام ابزار را به‌جای استاندارد عام ارائه نکرده‌ام.

## تمرین مستقل

برای قابلیت «ارسال reminder تکراری اثر دوم نسازد»، قرارداد SDD یک‌صفحه‌ای بنویس: سطح‌ها، artifact canonical، مسیر تغییر و stop condition.

**Rubric پاسخ:** پاسخ کامل spec-first را با نوشتن رفتار retry پیش از code، spec-anchored را با review مقابل Spec، و spec-as-source را فقط برای code تولیدشده از specification نگه‌داری‌شده و gate مکانیکی drift جدا می‌کند. policy کانال/opt-out را ledgerدار می‌گذارد، idempotency را به رفتار قابل مشاهده وصل می‌کند و به Agent اختیار تصمیم policy نمی‌دهد.

## جمع‌بندی

SDD یک برچسب واحد نیست. spec-first ترتیب روشن‌کردن رفتار، spec-anchored مرجع بازبینی و spec-as-source رابطهٔ مشتق‌سازی را توصیف می‌کنند. زنجیرهٔ Spec Kit نمونه‌ای مفید است، اما ارزش آن به gate، authority، provenance و بازخورد evidence بستگی دارد. درس بعد رفتار reschedule را به Spec قابل‌تست تبدیل می‌کند.

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

  • [GitHub Spec Kit](https://github.com/github/spec-kit/) — مستند رسمی ابزار و artifactهای آن؛ تعریف استاندارد و یگانهٔ SDD نیست.
  • [Martin Fowler — Understanding SDD: Kiro, Spec Kit and Tessl](https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html) — تحلیل روش جامعه‌محور از تعریف‌ها و ابزارهای رقیب.
  • [Kiro — Specs](https://kiro.dev/docs/specs/) — مستند رسمی یک workflow specمحور؛ قابلیت‌های محصول نسخه‌پذیرند.
  • [ISO/IEC/IEEE 29148:2018](https://www.iso.org/standard/72089.html) — استاندارد requirements engineering؛ SDD ابزارمحور را تجویز نمی‌کند.

به زبان ساده

Spec-first یعنی رفتار پیش از code روشن شود، Spec-anchored یعنی همان سند مرجع review بماند، و Spec-as-source یعنی artifact اجرایی واقعاً از Spec canonical تولید شود. خواندن یک Markdown و استخراج دستی task، به‌تنهایی Spec-as-source نیست.

مثال واقعی

در نمونهٔ رسمی GitHub Spec Kit، زنجیرهٔ `Spec → Plan → Tasks → Implement` یک workflow ابزارمحور است؛ این نام، استاندارد یگانه یا تضمین تولید کد صحیح نیست.

دانش‌سنجی

آزمون درس

۵ Q
01
در Brownfield، Spec مرجع review است اما taskها انسان تهیه می‌کند. این کدام رویکرد است؟
02
چه زمانی می‌توان بخشی از reschedule را spec-as-source نامید؟
03
policy adjacent slot هنوز DECIDE است. در قرارداد SDD چه می‌کنید؟
04
کدام زنجیره نقش artifactها را درست حفظ می‌کند؟
05
test تازه با Spec Accepted ناسازگار است. اولین کار چیست؟

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

برای reschedule قرارداد SDD بنویسید که سه سطح را از هم جدا کند.