برنامه‌ریزی، تحلیل و عملیات پلتفرم · فصل ۴ — Adapter، Capability، Shadow/Direct Publish و Quota · 214

Bounded Direct Publish با Idempotency و Verification

داده و event دارد اما آن‌ها را به مدل تصمیم، attention، experiment یا platform policy قابل توضیح تبدیل نمی‌کند. موضوع جاری: «Bounded Direct Publish با Idempotency و Verification». می‌تواند برای «Bounded Direct Publish با Idempotency و Verification» model، signal و guardrail لازم را در یک workflow محدود تعریف و ارزیابی کند.

Bounded Direct Publish with Idempotency and Verification — en-US

خلاصهٔ درس

داده و event دارد اما آن‌ها را به مدل تصمیم، attention، experiment یا platform policy قابل توضیح تبدیل نمی‌کند. موضوع جاری: «Bounded Direct Publish با Idempotency و Verification».

می‌تواند برای «Bounded Direct Publish با Idempotency و Verification» model، signal و guardrail لازم را در یک workflow محدود تعریف و ارزیابی کند.

خروجی این درس

می‌تواند برای «Bounded Direct Publish با Idempotency و Verification» model، signal و guardrail لازم را در یک workflow محدود تعریف و ارزیابی کند.

پیش‌نیازها

1. مسئله: Timeout یعنی «نمی‌دانم»، نه «حتماً Fail شد»

یک POST برای ساخت یا Publish ممکن است به Provider برسد اما پاسخ قبل از رسیدن به Client قطع شود. اگر همان Request را کورکورانه تکرار کنیم، ممکن است محتوای تکراری بسازیم. اگر هم فقط از ترس Duplicate هیچ کاری نکنیم، Transaction می‌تواند برای همیشه مبهم بماند. خروجی این درس Idempotent Publish Transaction & Verification Ledger v1 است.

2. مرز درس

PLN-023 فقط Transaction مستقیم Publish را از Intent تأییدشده تا Verification نهایی مدل می‌کند. Shadow promotion مربوط به PLN-022 و Account Health/Quota مربوط به PLN-024 خارج از Scope هستند. Lab کاملاً Synthetic است و هیچ Publish واقعی انجام نمی‌شود.

3. FACT خارجی و MAKNOW DESIGN

AIP-155 می‌گوید Request ID مشتری می‌تواند برای de-duplication، safe retry و idempotency guarantee استفاده شود، اما فقط وقتی API آن را واقعاً honor کند. Google Cloud نیز GET/PUT/DELETE را idempotent و POST/PATCH را ذاتاً non-idempotent می‌داند. Stateهای Ledger و retry budget این درس MAKNOW DESIGN هستند.

4. Transaction را قبل از Retry هویت‌دار کن

publish_transaction_id و publish_intent_id باید یک تصمیم Publish مشخص را به target_account و operation وصل کنند. Retry نباید یک Intent جدید یا Account دیگر را ناخواسته اجرا کند.

5. Payload Hash بخشی از Request Identity است

payload_hash فقط برای Debug نیست. اگر همان idempotency key یا request ID با payload دیگری استفاده شود، سیستم نباید آن را «همان Transaction» بداند. Key reuse با payload متفاوت باید DUPLICATE_BLOCKED یا معادل fail-closed بدهد.

6. Provider Support را صریح ثبت کن

idempotency_support مشخص می‌کند Provider آیا request identity را تضمین می‌کند یا نه. وجود Header دلخواه در Client به معنی Provider support نیست. اگر Provider مکانیزم رسمی ندارد، باید application-side duplicate strategy را جدا نام‌گذاری کنیم.

7. Retry Class و Execution Budget را محدود کن

attempt_no، retry_class و execution_budget جلوی retry بی‌نهایت را می‌گیرند. Timeout با request identity معتبر می‌تواند Retry-safe باشد؛ Timeout بدون identity و بدون duplicate/read-back evidence باید AMBIGUOUS بماند.

8. Response Status فقط یک Evidence است

200/201/202 می‌گوید Provider چه Responseای داده، نه اینکه دقیقاً همان Resource موردنظر و فقط یک‌بار ایجاد شده است. provider_resource_id باید به Intent و Account صحیح bind شود.

9. Read-back Verification را از Response جدا کن

verification_method و read_back_snapshot برای اثبات state نهایی‌اند. Verification می‌تواند resource ID، target account، payload fingerprint یا fieldهای بحرانی را دوباره بخواند. اگر read-back در دسترس نیست، VERIFIED را جعل نکن.

10. Duplicate Detection باید قابل‌ردیابی باشد

duplicate_detection می‌تواند Provider request ID، application duplicate key یا query/read endpoint باشد. اما نوع مکانیزم و محدودیت آن باید در Provenance ثبت شود؛ application key هرگز provider-side exactly-once را اثبات نمی‌کند.

11. Freshness و Provenance بخشی از Transaction هستند

مستند idempotency، retention window یا verification endpoint ممکن است عوض شود. Evidence قدیمی → STALE_EVIDENCE. Evidence بدون provenance_ref → UNKNOWN یا BLOCKED. برای تصمیم Direct Publish، حدس جای سند را نمی‌گیرد.

12. Baseline — Timeout با Request ID معتبر

در Baseline، Provider request ID رسمی را پشتیبانی می‌کند. Attempt اول Timeout می‌شود؛ Retry با همان request ID و همان payload hash انجام می‌شود؛ Provider همان Resource را برمی‌گرداند و read-back Account/Payload را تأیید می‌کند. نتیجه VERIFIED است.

case_ididempotency_supportattempt_noresponse_statusverification_methodpublish_stateretry_decisioncontrol_reason
baseline_provider_request_idPROVIDER_REQUEST_ID2201READ_BACKVERIFIEDNO_RETRYREAD_BACK_MATCHES_INTENT
timeout_no_identityNONE1TIMEOUTNONEAMBIGUOUSHOLD_AND_INVESTIGATETIMEOUT_WITHOUT_SAFE_IDENTITY_OR_DUPLICATE_CHECK
key_reused_different_payloadPROVIDER_REQUEST_ID2409READ_BACKDUPLICATE_BLOCKEDBLOCKEDREQUEST_ID_REUSED_FOR_DIFFERENT_PAYLOAD
success_wrong_targetPROVIDER_REQUEST_ID1201READ_BACKFAILEDBLOCKEDREAD_BACK_TARGET_MISMATCH
budget_exhausted_unverifiedPROVIDER_REQUEST_ID3TIMEOUTREAD_BACKUNVERIFIEDDEFERREDEXECUTION_BUDGET_EXHAUSTED
stale_idempotency_evidencePROVIDER_REQUEST_ID1201READ_BACKSTALE_EVIDENCEBLOCKEDDECISIVE_EVIDENCE_STALE
missing_provenancePROVIDER_REQUEST_ID1201READ_BACKUNKNOWNBLOCKEDPROVENANCE_MISSING
transfer_app_duplicate_read_before_retryAPPLICATION_DUPLICATE_KEY_ONLY2TIMEOUT_THEN_READ_FOUNDREAD_BEFORE_RETRYVERIFIEDNO_RETRYREAD_BACK_MATCHES_INTENT

13. Shortcutهای خطرناک

  1. Timeout را Fail قطعی فرض کنی. ۲) POST را بدون identity دوباره بفرستی. ۳) یک idempotency key را برای payload جدید reuse کنی. ۴) 2xx را exactly-once proof بدانی. ۵) Resource متعلق به Account دیگر را success حساب کنی. ۶) بعد از تمام‌شدن budget باز هم retry کنی.

14. Transfer — Provider بدون Idempotency Key رسمی

در Transfer، Provider request ID رسمی ندارد اما read endpoint قابل‌اتکا دارد. Client یک application duplicate key را از Intent+Target+Payload می‌سازد، قبل از Retry read-before-retry انجام می‌دهد و فقط اگر Resource موجود مطابق Intent پیدا نشد و budget اجازه داد Request جدید می‌فرستد. نتیجه می‌تواند VERIFIED شود، ولی provider_exactly_once=false باقی می‌ماند.

15. Lab، Assessment و Freshness

در lab/PLN-023-LAB1/learner/ دستور python run_checks.py را اجرا کن. هشت Fixture مسیرهای VERIFIED، AMBIGUOUS، DUPLICATE_BLOCKED، FAILED/UNVERIFIED، DEFERRED، STALE_EVIDENCE، UNKNOWN و Transfer را پوشش می‌دهند. AIP-155 و Google Cloud HTTP guidance در 2026-09-16 دوباره بررسی شده‌اند.

ارزیابی

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

PLN-023-S1 retrieval

Why is approved publish intent different from request identity?

lesson ✗AI ✗notes ✗

PLN-023-S2 application

Build the ledger for a timed-out create request with a provider request ID.

lesson ✗AI ✗notes ✗

PLN-023-S3 diagnosis

Why does a 201 response not by itself prove exactly-once publish?

lesson ✗AI ✗notes ✗

PLN-023-S4 transfer

Design read-before-retry for a provider with no documented idempotency key.

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

Critical dimensions: lesson boundary; transaction/request identity; payload-key binding; finite retry budget; response versus read-back verification; duplicate detection; freshness/provenance; changed-context transfer.

A passing response must preserve AMBIGUOUS/UNVERIFIED/UNKNOWN/STALE states when evidence is incomplete and must not claim provider-side exactly-once from application-side controls.

منابع و تازگی

AIP-155: Request identification
·
Request IDs can support de-duplication, retry safety and idempotency guarantees when the API honors them.
HTTP guidelines — Google Cloud APIs
·
GET, PUT and DELETE are idempotent by HTTP method semantics; POST and PATCH are not idempotent by method semantics alone.

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

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

کاملاً آفلاین است؛ API Key و Network لازم نیست.

  1. fixtures/cases.json را بررسی کن.
  2. python run_checks.py را اجرا کن.
  3. هر بار فقط یک Field تعیین‌کننده مثل Request Identity، Payload Hash، Target Account، Read-back، Provenance، Freshness یا Retry Budget را تغییر بده.
  4. علت تغییر State را توضیح بده و هیچ اثر واقعی Provider را ادعا نکن.