# كيف يعمل

> ما يجري داخل mailctl بين قراءة الإعداد وتطبيق الخطة.

كل أمر يمرّ بالمسار نفسه. معرفته تشرح معظم سلوك mailctl: لماذا يتوقف التطبيق الأول في منتصف الطريق، ولماذا تكون إعادة التشغيل آمنة دائمًا، ولماذا تُرفض بعض الإعدادات بدل قبولها.

## المسار

_كل أمر يحمّل ملف الإعداد ويقرأ الحالة الحية ويحدد السجلات المطلوبة ثم يقارن ويرتّب الإجراءات، فيطبعها plan وينفّذها apply_

_كل أمر يحمّل ملف الإعداد ويقرأ الحالة الحية ويحدد السجلات المطلوبة ثم يقارن ويرتّب الإجراءات، فيطبعها plan وينفّذها apply_

1.  **التحميل.** يُحلَّل ملف YAML بصرامة. المفتاح المجهول خطأ يذكر رقم سطره، وتُطبَّق القواعد بين الحقول قبل أي اتصال بالشبكة، فيفشل الخطأ في الملف مبكرًا بدل أن يفشل في منتصف التطبيق.
    
2.  **القراءة.** لكل نطاق يقرأ mailctl منطقة Cloudflare ويسأل كل مزوّد بريد عن حالته الحية: النطاقات وصناديق البريد والأسماء البديلة والالتقاط الشامل.
    
3.  **المطلوب.** يحدد كل مزوّد سجلات DNS التي يحتاجها. تُجمع تلك القوائم، وتضيف طبقة قابلية التسليم DMARC وMTA-STS وTLS-RPT وBIMI، وتدمج متطلبات SPF لكل مزوّد في سجل واحد.
    
4.  **المقارنة.** تُقارن الحالة المطلوبة بالحالة الحية. كل ما ينقص يصير `CREATE`، وكل ما يختلف `UPDATE`، ومع `-prune` يصير كل ما لم يعد الإعداد يذكره `DELETE`.
    
5.  **الترتيب.** توضع الإجراءات في الترتيب الوحيد الذي ينجح (انظر أدناه).
    
6.  **الطباعة أو التنفيذ.** يتوقف `plan` هنا ويطبع. وينفّذ `apply` القائمة نفسها، سطرًا لكل إجراء، ويتوقف عند أول خطأ.
    

لا تُخزَّن أي حالة بين التشغيلات. ملف الإعداد والمزوّدون هم مصادر الحقيقة الوحيدة، فلا شيء ينحرف أو يُقفل أو يحتاج إلى إصلاح.

## لماذا يهم الترتيب

تُنفَّذ الإجراءات داخل النطاق بترتيب ثابت:

 
| الخطوة | لماذا تأتي هناك |
| --- | --- |
| 
MTA-STS Worker

 | 

يجب أن تُقدَّم السياسة قبل أن يعلن سجل TXT `_mta-sts` معرّفها الجديد. وإلا جلب الخادم المستقبِل السياسة القديمة تحت المعرّف الجديد واحتفظ بها.

 |
| 

سجلات DNS

 | 

يفحص مزوّدو البريد DNS عند إضافة نطاق. يرفض Purelymail النطاق حتى يُحَلّ سجل TXT الخاص بملكيته.

 |
| 

كائنات مزوّد البريد

 | 

يرتّب كل مزوّد إجراءاته بنفسه، بدءًا بالنطاق، لأن صناديق البريد والأسماء البديلة لا يمكن أن توجد قبله.

 |

لهذا يتوقف أول `apply` عادة برسالة "DNS ownership checks did not pass": نُشرت السجلات قبل لحظة ولم تنتشر بعد. انتظر، وشغّل `apply` مرة أخرى، فتُتخطّى الإجراءات المكتملة.

## كيف يُحكم على تعارضات DNS

لكل سجل يريده mailctl دور: MX أو SPF أو DKIM أو DMARC أو الملكية أو MTA-STS أو TLS-RPT أو BIMI. والدور يحدد أي السجلات القائمة يُعدّ تعارضًا.

-   السجل القائم المطابق أصلًا يُترك كما هو. تُقارن الأسماء دون تمييز لحالة الأحرف ودون النقطة الأخيرة.
    
-   سجل SPF أو MTA-STS أو TLS-RPT أو BIMI يتعارض فقط مع سجل TXT له وسم الإصدار نفسه. سجلات TXT الأخرى على جذر النطاق لا تُمس.
    
-   يعيش DKIM وDMARC على أسماء يملكها mailctl بالكامل، فأي شيء آخر هناك تعارض.
    
-   سجلات TXT للملكية لا تتعارض أبدًا: قد يكون لكل مزوّد سجله.
    

يوقف التعارض الخطة بخطأ يذكر السجل. مرّر `-replace-dns` لاستبداله بدل ذلك. لا يُكتب فوق أي شيء افتراضيًا.

قد يقترح مزوّدان على نطاق واحد محتوى مختلفًا لسجل يجب أن يكون فريدًا، مثل DMARC. هذا خطأ في الإعداد يبلّغ عنه `plan` و`audit` كلاهما، بدل سباق على أيهما يفوز.

## الخطة والتطبيق متّفقان

`apply` بلا وسائط يخطّط من جديد وينفّذ النتيجة، فيعمل دائمًا على الحالة الحالية. و`apply -plan saved.json` ينفّذ خطة حُفظت سابقًا بـ `plan -json`، ويرفض إن تغيّرت الحالة الحية منذ إعدادها. استخدم الصيغة الثانية حين يراجع شخص الخطة ويطبّقها شيء آخر.

كل إجراء آمن التكرار. إعادة التشغيل بعد تطبيق جزئي تنفّذ ما تبقّى فقط. والنطاق المتقارب كليًا يبلّغ `No changes.`

## الإجراءات اليدوية

بعض التغييرات لا يمكن إجراؤها عبر واجهة المزوّد. تظهر في الخطة بوسم `MANUAL` مع المكان الذي تُجرى فيه، مثل مركز إدارة Microsoft 365. لا ينفّذها `apply` أبدًا، والخطة التي لم يتبقَّ فيها إلا إجراءات يدوية تُعدّ متقاربة.

## التدقيق شيء مختلف

يسأل `plan` المزوّدين عمّا يحتفظون به. أما `audit` فيسأل الإنترنت: يحلّ السجلات المنشورة عبر محلّل حقيقي ويجلب سياسة MTA-STS عبر HTTPS. واجهة المزوّد تبلّغ بما طلبته، و`audit` يبلّغ بما سيراه الخادم المستقبِل. شغّله بعد أن يأخذ DNS وقته في الانتشار.

## خريطة الشيفرة

للمساهمين، كل خطوة تعيش في حزمة واحدة تحت `internal/`:

 
| الحزمة | الدور |
| --- | --- |
| 
`config`

 | 

مخطط YAML والتحميل الصارم والتحقق

 |
| 

`engine`

 | 

يحوّل الإعداد والحالة الحية إلى خطة مرتّبة، وينفّذها

 |
| 

`plan`

 | 

قائمة الإجراءات وترتيبها وعرضها

 |
| 

`dns`، `dns/cloudflare`

 | 

نموذج السجلات وقواعد التعارض وعميل منطقة Cloudflare

 |
| 

`deliver`

 | 

دمج SPF وسجلات DMARC وMTA-STS وTLS-RPT وBIMI

 |
| 

`mail/*`

 | 

حزمة لكل مزوّد بريد، خلف واجهة واحدة

 |
| 

`worker`

 | 

يرفع Worker سياسة MTA-STS

 |
| 

`audit`

 | 

يفحص DNS المنشور عبر محلّل

 |
| 

`secret`، `keychain`

 | 

تحديد بيانات الاعتماد وسلسلة مفاتيح macOS

 |
| 

`cli`، `ui`، `planjson`

 | 

سطر الأوامر وصفحة الإدارة وعقد JSON

 |
