برنامه‌ریزی، تحلیل و عملیات پلتفرم · فصل ۱ — Message، Identity، Contact، Opportunity و Obligation · 192

Unified Inbox و Channel-normalized Messages

داده و event دارد اما آن‌ها را به مدل تصمیم، attention، experiment یا platform policy قابل توضیح تبدیل نمی‌کند. موضوع جاری: «Unified Inbox و Channel-normalized Messages». می‌تواند برای «Unified Inbox و Channel-normalized Messages» model، signal و guardrail لازم را در یک workflow محدود تعریف و ارزیابی کند.

Unified Inbox and Channel-Normalized Messages — en-US

خلاصهٔ درس

داده و event دارد اما آن‌ها را به مدل تصمیم، attention، experiment یا platform policy قابل توضیح تبدیل نمی‌کند. موضوع جاری: «Unified Inbox و Channel-normalized Messages».

می‌تواند برای «Unified Inbox و Channel-normalized Messages» model، signal و guardrail لازم را در یک workflow محدود تعریف و ارزیابی کند.

خروجی این درس

می‌تواند برای «Unified Inbox و Channel-normalized Messages» model، signal و guardrail لازم را در یک workflow محدود تعریف و ارزیابی کند.

پیش‌نیازها

1. مسئله واقعی: Inbox واحد بدون حفظ منبع، امن نیست

یک Email، Web Form و Chat ممکن است درباره یک خرید واحد باشند، اما شناسه، زمان، Thread و Attachment آن‌ها یک semantics مشترک ندارند. هدف این درس ساختن یک Normalized Message قابل‌ممیزی است؛ نه یکی‌کردن هویت افراد. هر رکورد باید بتواند به رویداد خام خودش برگردد و هر تصمیم dedupe یا parse باید از شواهد قابل‌مشاهده دفاع شود.

2. مرز مالکیت درس

PLN-001 فقط Channel Normalization را مالک است: Raw Message را به یک Envelope پایدار تبدیل می‌کند و provenance، dedupe و parse state را نگه می‌دارد. تشخیص اینکه دو handle متعلق به یک Person هستند در PLN-002 است. بنابراین participant_handles را حفظ می‌کنیم، اما canonical_person_id تولید نمی‌کنیم.

3. CloudEvents چه چیزی به ما می‌آموزد

CloudEvents یک قالب vendor-neutral برای Event تعریف می‌کند و چهار context attribute اجباری id، source، specversion و type دارد. همچنین source + id مرز مفیدی برای تشخیص duplicate در همان context است. ما از این ایده برای طراحی envelope الهام می‌گیریم، ولی schema Inbox خود MAKNOW را به CloudEvents نسبت نمی‌دهیم.

4. Provenance باید از UI مستقل بماند

W3C PROV نشان می‌دهد provenance باید بین سیستم‌ها قابل نمایش و تبادل باشد. در این درس provenance_pointer یعنی مسیری که نشان می‌دهد این Envelope از کدام Raw Event، Adapter و Normalization Version آمده است. اگر UI عوض شود، این lineage نباید گم شود.

5. Envelope پایدار را از فیلدهای ضروری شروع کن

حداقل فیلدهای عملی این درس عبارت‌اند از: channel، raw_message_ref، external_message_id، source_system، occurred_at، received_at، participant_handles، body_ref، attachment_refs، normalization_version، provenance_pointer، dedupe_key، parse_state، unsupported_fields و ingest_decision. thread_hint ممکن است منبع‌های متفاوتی داشته باشد و نباید جعل شود.

6. occurred_at و received_at یکی نیستند

occurred_at زمان رخداد نزد منبع است؛ received_at زمان دریافت در Inbox. Retry می‌تواند received_at تازه داشته باشد ولی همان رویداد قبلی باشد. حذف یکی از این دو زمان، تشخیص تأخیر، replay و ترتیب رویدادها را ضعیف می‌کند.

7. Raw Ref و External Message ID هر دو لازم‌اند

external_message_id شناسه‌ای است که Provider یا Source System می‌دهد. raw_message_ref مسیر بازیابی payload خام یا snapshot آن است. یکی جای دیگری را نمی‌گیرد: External ID برای correlation و dedupe مفید است؛ Raw Ref برای audit، replay و بازتفسیر نسخه‌های بعدی Normalizer لازم است.

8. Dedupe Key باید Channel-scoped و Context-scoped باشد

یک dedupe key خوب باید حداقل context منبع را حفظ کند. در Lab از ترکیب workspace_scope + channel + source_system + external_message_id استفاده می‌کنیم. این policy فقط برای fixture آموزشی است، اما اصل مهم روشن است: همان External ID در workspace دیگری نباید به‌صورت خام با رکورد قبلی collision کند.

9. Replay را با «پیام جدید» اشتباه نگیر

اگر Provider همان event را دوباره با received_at جدید تحویل دهد، Envelope می‌تواند دوباره ساخته شود، اما dedupe_state=REPLAY باید downstream action را به SUPPRESS_REPLAY ببرد. تغییر زمان دریافت به‌تنهایی دلیل ساختن Message جدید نیست.

10. Thread Hint شاهد است، نه حقیقت کانونی

بعضی channelها thread ID صریح دارند؛ Email ممکن است فقط reply headers داشته باشد؛ Form ممکن است اصلاً thread نداشته باشد. thread_hint باید منبع خودش را نشان دهد. اگر provider thread ID حذف شد ولی reply header معتبر باقی ماند، می‌توان hint را از همان header ساخت، بدون جعل شناسه Provider.

11. Parse State باید Partial و Unsupported را تحمل کند

یک Attachment با content type ناشناخته نباید خودکار باعث از دست‌رفتن Body معتبر شود. parse_state=PARTIAL_UNSUPPORTED و unsupported_fields امکان می‌دهد پیام اصلی Normalized بماند، درحالی‌که بخش نامفهوم برای پردازش بعدی علامت‌گذاری می‌شود. اما کمبود فیلدهای حیاتی مانند Raw Ref یا Provenance می‌تواند کل ingest را به QUARANTINED ببرد.

12. Normalization حق Merge هویت ندارد

وجود Email، Chat و Form در یک Inbox ثابت نمی‌کند handleهای آن‌ها یک شخص‌اند. اگر Adapter فیلدی مانند resolved_person_id یا دستور Merge قطعی وارد کند، Normalizer باید آن را به‌عنوان عبور از مرز scope تشخیص دهد؛ نه اینکه بی‌صدا آن را Canonical کند.

13. Worked Example: Email با Attachment

فرض کنید Email با External ID m-204، Raw Ref پایدار، زمان رخداد و دریافت، participant handles، Body Ref و Attachment Ref می‌رسد. با provenance کامل و content type شناخته‌شده، Envelope NORMALIZED است، dedupe key از context منبع ساخته می‌شود و identity همچنان unresolved می‌ماند.

14. Failure Probeهای قطعی

چهار probe را اجرا کن: همان event با received_at جدید باید Replay تشخیص داده شود؛ نبود provider thread ID با reply header معتبر نباید جعل ID ایجاد کند؛ External ID یکسان در workspace دیگر نباید collision بسازد؛ Attachment ناشناخته باید typed unsupported state تولید کند. Raw Ref یا Provenance مفقود نیز باید از happy path خارج شود.

15. Transfer: Thread ID حذف شده، Reply Header باقی است

در Transfer، Provider دیگر thread ID نمی‌دهد ولی Email reply header و تمام source references باقی‌اند. Envelope را از شواهد جدید دوباره بساز: thread_hint را با source مشخص از reply header استخراج کن، dedupe key را از context واقعی محاسبه کن و Identity را unresolved نگه دار. نتیجه نباید از baseline کپی شود.

ارزیابی

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

F1 retrieval

lesson ✗AI ✗notes ✗

F2 diagnosis

lesson ✗AI ✗notes ✗

S1 application

lesson ✗AI ✗notes ✗

S2 diagnosis

lesson ✗AI ✗notes ✗

S3 decision

lesson ✗AI ✗notes ✗

S4 transfer

lesson ✗AI ✗notes ✗
ملاک‌های ارزیابی (rubric)
DimensionSufficient evidenceBlocking failure
BoundaryChannel normalization is owned; person identity stays unresolvedNormalization silently merges identity
Source fidelityRaw reference, external ID, source and provenance remain visibleCanonical envelope destroys source traceability
Dedupe/replayDedupe key is context-scoped and replay is explicitLater received_at is treated as a new message without evidence
Parse uncertaintyUnsupported/partial states remain typedUnknown attachment or missing evidence is coerced into success
TransferThread hint and dedupe evidence are recomputed from changed inputBaseline result or provider thread ID is copied/fabricated

منابع و تازگی

CloudEvents Specification
·
Required CloudEvents context attributes and source+id duplicate guidance; not MAKNOW inbox semantics.
PROV-O: The PROV Ontology — W3C Recommendation
·
Model and interchange of provenance across systems/contexts; not MAKNOW message identity or dedupe policy.

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

تصاویر درس

PLN-001-NORMALIZATION-FLOW

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

Use only the supplied synthetic records. Implement normalize(case) in starter.py. Preserve source references and provenance, derive a context-scoped dedupe key, keep replay/unsupported states explicit, and never perform cross-channel identity merge.

Run python run_checks.py. The learner checker validates output shape and boundary safety only; expected labels and reference logic remain outside learner-publishable paths.