امنیت، هویت، استقرار و تاب‌آوری · فصل ۶ — Chaos، Feature Flags، Rollout و ADR · 108

Architecture Change Control, ADR و Supersession

می‌تواند سرویس را اجرا کند اما lifecycle، health، rollout، observability و recovery را به‌صورت سیستماتیک مدیریت نمی‌کند. موضوع جاری: «Architecture Change Control, ADR و Supersession». می‌تواند برای «Architecture Change Control, ADR و Supersession» run/release model و signals/recovery checks لازم را برای یک سرویس محدود طراحی کند.

Architecture Change Control, ADR and Supersession — en-US

خلاصهٔ درس

می‌تواند سرویس را اجرا کند اما lifecycle، health، rollout، observability و recovery را به‌صورت سیستماتیک مدیریت نمی‌کند. موضوع جاری: «Architecture Change Control, ADR و Supersession».

می‌تواند برای «Architecture Change Control, ADR و Supersession» run/release model و signals/recovery checks لازم را برای یک سرویس محدود طراحی کند.

خروجی این درس

می‌تواند برای «Architecture Change Control, ADR و Supersession» run/release model و signals/recovery checks لازم را برای یک سرویس محدود طراحی کند.

پیش‌نیازها

1. مسئله: تصمیم معماری اگر فقط در چت بماند، قابل حسابرسی نیست

یک تصمیم معماری ممکن است ابتدا در جلسه یا چت شکل بگیرد، بعد در کد اجرا شود و چند ماه بعد هیچ‌کس نداند چرا آن انتخاب انجام شده است. مشکل شدیدتر زمانی رخ می‌دهد که متن تصمیم پذیرفته‌شده بعداً بی‌سروصدا ویرایش شود؛ در این حالت تاریخچه از بین می‌رود و reviewer نمی‌تواند تشخیص دهد تصمیم اولیه چه بوده، چه چیزی تغییر کرده و چرا.

خروجی این درس Architecture Decision Supersession Record v1 است. این رکورد decision را از implementation جدا نگه می‌دارد، accepted history را حفظ می‌کند، supersession را صریح ثبت می‌کند و drift بین تصمیم جاری و شواهد اجرا را پنهان نمی‌کند.

2. ADR چیست و چه چیزی را ثبت می‌کند

ADR یا Architecture Decision Record برای ثبت یک انتخاب معماری مهم استفاده می‌شود. در راهنمای AWS، هر ADR تصمیم، context و consequences را ثبت می‌کند و مجموعه ADRها یک decision log می‌سازد. هدف اصلی این است که فقط «چه چیزی انتخاب شد» نماند؛ دلیل، شرایط و trade-offهای انتخاب هم برای اعضای فعلی و آینده قابل بازیابی باشد.

ADR یک architecture specification کامل نیست. همچنین جای implementation، test یا runtime evidence را نمی‌گیرد. آن را به‌عنوان رکورد تصمیم ببین، نه اثبات اجرای تصمیم.

3. Lifecycle: Proposed، Accepted، Rejected و Superseded

یک ADR معمولاً از حالت Proposed وارد review می‌شود. تیم می‌تواند آن را برای rework باز نگه دارد، Reject کند یا Accept کند. راهنمای AWS می‌گوید پس از acceptance، ADR به‌عنوان یک رکورد immutable در نظر گرفته می‌شود. اگر insight جدید تصمیم را تغییر دهد، راه درست ساخت ADR جدید و طی‌کردن review جدید است.

وقتی ADR جدید پذیرفته شد، ADR قبلی Superseded می‌شود. این به معنی پاک‌کردن یا بازنویسی ADR قدیمی نیست؛ تصمیم قدیمی باید در decision log باقی بماند تا زنجیره تاریخ قابل ردیابی باشد.

4. حداقل محتوای یک ADR قابل review

حداقل مفید برای ADR شامل Context، Decision و Consequences است. AWS همچنین status و changelog را برای reviewability لازم می‌داند و توصیه می‌کند context راه‌حل‌های بررسی‌شده را هم نشان دهد. در این درس، برای evidence دقیق‌تر Alternatives و Trade-offs را نیز صریح ثبت می‌کنیم.

اگر یک یادداشت فقط بگوید «از Kafka استفاده می‌کنیم» یا «PostgreSQL انتخاب شد»، هنوز معلوم نیست مشکل چه بوده، گزینه‌های دیگر چه بوده‌اند و چه هزینه‌هایی پذیرفته شده است. چنین یادداشتی برای change control ضعیف است.

5. Architecturally significant را از انتخاب جزئی جدا کن

هر تغییر کد ADR نمی‌خواهد. تصمیم‌هایی که ساختار، non-functional requirements، dependencyها، interfaceهای منتشرشده یا construction techniqueهای مهم را تغییر می‌دهند معمولاً معماری‌ترند. در مقابل، نام یک متغیر محلی یا یک refactor بی‌اثر روی boundary و رفتار سیستم معمولاً ADR مستقل لازم ندارد.

این مرز کاملاً مکانیکی نیست. judgment انسانی لازم است: اگر انتخاب، دامنه تغییر، coupling، operational behavior یا هزینه برگشت معنی‌داری ایجاد می‌کند، ثبت آن به‌عنوان ADR قابل دفاع‌تر می‌شود.

6. Decision Log و مالکیت تصمیم

ADR منفرد زمانی ارزش بیشتری دارد که در یک decision log مرکزی قرار گیرد. هر رکورد باید ID، status، owner/date و ارتباطش با تصمیم‌های قبلی را روشن کند. تاریخچه تغییر نیز باید نشان دهد چه کسی و چه زمانی state یا metadata مجاز را تغییر داده است.

این مالکیت به معنی «مالک تصمیم هرگز اشتباه نمی‌کند» نیست. یعنی مسئول review، ارتباط و نگهداری record مشخص است و تغییر تصمیم از مسیر قابل ردیابی انجام می‌شود.

7. Supersession: تغییر تصمیم بدون پاک‌کردن گذشته

فرض کن ADR-002 قبلاً accepted شده و انتخاب A را ثبت کرده است. حالا constraints جدید نشان می‌دهد B مناسب‌تر است. anti-pattern این است که ADR-002 را باز کنی و متن Decision را از A به B تغییر دهی. با این کار مشخص نمی‌شود سیستم در دوره قبل بر چه مبنایی طراحی شده بود.

الگوی سالم: ADR-003 را بساز، context جدید و alternatives را ثبت کن، آن را review کن و اگر accepted شد، در ADR-003 فیلد supersedes: ADR-002 را قرار بده؛ سپس وضعیت ADR-002 را Superseded کن و هر دو را نگه دار.

8. Documentation state با Implementation state یکی نیست

ممکن است decision log کاملاً درست باشد اما runtime هنوز مطابق تصمیم قدیمی کار کند. بنابراین Accepted بودن ADR جدید به‌تنهایی conformance را ثابت نمی‌کند. برای change control، باید implementation evidence جداگانه داشته باشی: code/config snapshot، manifest، test یا architecture check متناسب با scope.

در این درس، پیوند ADR با implementation evidence یک extension آموزشی MAKNOW است. هدف این است که «تصمیم پذیرفته‌شده» را با «چیزی که واقعاً مشاهده شده» یکی نگیریم.

9. Architecture Drift را OPEN نگه دار

اگر active ADR می‌گوید interaction باید async باشد ولی manifest هنوز sync path قدیمی را نشان می‌دهد، document را تغییر نده تا با runtime جور شود. discrepancy را به‌عنوان drift ثبت کن. Record باید بگوید evidence چیست، conformance فعلی چیست، review trigger چیست و reconciliation action چه خواهد بود.

وقتی evidence کافی نیست نیز نتیجه را UNKNOWN نگه دار. نداشتن شاهد مجوز ساختن نتیجه مثبت نیست.

10. Failure probe: ویرایش silent یک Accepted ADR

در fixture اول، checksum نسخه تاریخی ADR با نسخه فعلی یکی نیست و ADR قبلاً Accepted بوده است. سبز بودن tests یا درست بودن تصمیم جدید این مشکل را پاک نمی‌کند. ابتدا باید historical record preserved شود یا نسخه معتبر آن بازیابی شود؛ سپس change از طریق ADR جدید دنبال شود.

اگر accepted history را rewrite کنی، بعداً نمی‌توانی causal chain تصمیم و implementation قبلی را بازسازی کنی. این شکست اصلی تمرین است.

11. Failure probe: دو ADR پذیرفته‌شده بدون supersedes link

حالت دوم ظاهراً تمیزتر است: ADR قدیمی و جدید هر دو وجود دارند و هر دو Accepted هستند، اما ADR جدید مشخص نمی‌کند کدام تصمیم را supersede می‌کند. نتیجه دو تصمیم ظاهراً current و متعارض است.

Repair باید relationship را صریح کند و review state را دوباره معتبر سازد. صرفاً جدیدتر بودن timestamp نباید به‌صورت مخفیانه تعیین کند کدام تصمیم active است.

12. Record را ردیفی و evidence-first بساز

برای هر تصمیم این ستون‌ها را پر کن: ADR ID، Status، Context، Alternatives، Decision، Consequences، Supersedes، Implementation Evidence، Conformance، Drift، Review Trigger و Reconciliation Action. هر conclusion باید به observation یا authority مشخص متصل باشد.

سه نوع statement را قاطی نکن: direct evidence، inference/policy choice و unknown. این تفکیک باعث می‌شود reviewer بداند کدام بخش مشاهده شده و کدام بخش judgment است.

13. Reconciliation Action باید متناسب با mismatch باشد

اگر مشکل فقط missing supersedes link است، repair در decision history انجام می‌شود. اگر decision chain درست است ولی code با تصمیم فعال نمی‌خواند، action روی implementation یا روی تصمیم جدید خواهد بود. اگر evidence ناقص است، action اول جمع‌آوری evidence است، نه force کردن PASS.

هدف «سبز کردن جدول» نیست؛ هدف این است که وضعیت فعلی و مسیر reconciliation قابل دفاع باشند.

14. Lab: زنجیره تصمیم را از fixture بازسازی کن

تمرین محلی هشت case مصنوعی دارد: baseline سالم، accepted-history tamper، missing supersedes link، implementation drift، تصمیم trivial، proposal هنوز پذیرفته‌نشده، decision rejected و یک transfer با مسئله معماری متفاوت. run_checks.py فقط ساختار fixture را بررسی می‌کند؛ پاسخ تصمیم را در starter قرار نداده است.

در starter.py هشت dimension را برای هر case برگردان: decision status، historical integrity، option set، supersession link، active decision، implementation conformance، drift register و significance judgment. هر چیزی که از evidence قابل اثبات نیست باید OPEN/UNKNOWN بماند.

15. Transfer: یک decision chain متفاوت را از صفر بساز

در transfer، موضوع تصمیم، alternatives، status history و mismatch اجرا تغییر می‌کنند. identifier یا نتیجه case اول را کپی نکن. ابتدا significance را بسنج، context و option set را بساز، active decision را از status/supersession chain استخراج کن و بعد implementation evidence را با همان active decision مقایسه کن.

خروجی زمانی قابل دفاع است که accepted history حفظ شده باشد، supersession صریح باشد، documentation و runtime evidence جدا سنجیده شوند، و هیچ drift یا unknown با rewrite کردن تاریخچه پنهان نشده باشد.

ارزیابی

پاسخ‌نامه‌ی این درس در بسته‌ی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار می‌فرستد.

Q1 retrieval

What changes after an ADR is accepted if new insight requires a different architecture decision?

lesson ✗AI ✗notes ✗

Q2 application

An accepted ADR has been silently edited. What must the change-control record do first?

lesson ✗AI ✗notes ✗

Q3 diagnosis

The ADR chain is valid but code still implements the superseded decision. How should the state be recorded?

lesson ✗AI ✗notes ✗

Q4 decision

A developer wants an ADR for a local variable rename. What should be checked before creating one?

lesson ✗AI ✗notes ✗

Q5 transfer

A second repository has different alternatives and a new status history. How is the current decision determined?

lesson ✗AI ✗notes ✗
ملاک‌های ارزیابی (rubric)

A passing response must:

  • preserve accepted decision history instead of silently rewriting it;
  • capture context, alternatives, decision, consequences, status, and change relationship for an architecturally significant choice;
  • make supersession explicit and derive the active decision from the decision chain rather than timestamp recency;
  • compare implementation evidence with the active decision and keep nonconformance as OPEN drift;
  • preserve UNKNOWN when evidence is insufficient;
  • distinguish an architecturally significant choice from a trivial local code preference;
  • rebuild the transfer case independently rather than copying identifiers or the first-case conclusion.

منابع و تازگی

AWS Prescriptive Guidance — Using architectural decision records to streamline decision-making during development
·
AWS Prescriptive Guidance — Architectural decision record process
·
AWS Prescriptive Guidance — Best practices for using architectural decision records
·
AWS Prescriptive Guidance — FAQ about architectural decision records
·

مطالعهٔ موارد (case studies)

تصاویر درس

OPS015-VIS1

فایل‌های آزمایشگاه

This exercise uses synthetic local evidence only. No production repository, credential, customer data, or external service is required.

  1. Run python run_checks.py to verify the fixture structure.
  2. Implement analyze_change(case) in starter.py.
  3. For each case, return these eight keys: decision_status, historical_integrity, option_set, supersession_link, active_decision, implementation_conformance, drift_register, significance_judgment.
  4. Base every value on the supplied fields. Keep unsupported conclusions OPEN or UNKNOWN.
  5. Rebuild the transfer case from its own concern, alternatives, status history, and implementation evidence. Do not copy the baseline decision.

The structural check does not reveal the expected classifications. It only proves that the evidence needed for the exercise is present.