diff --git a/src/SUMMARY.md b/src/SUMMARY.md
index 4f764f2..44ab76b 100644
--- a/src/SUMMARY.md
+++ b/src/SUMMARY.md
@@ -37,6 +37,7 @@
- [التمثيل الوسيط SIR](backend/sir.md)
- [توليد LLVM (المترجم sadc)](backend/llvm.md)
- [الآلة الافتراضية (VM)](backend/vm.md)
+- [دراسة حالة: توحيد هاش/شفّر/فك_تشفير](backend/crypto-unification.md)
# الجزء السادس · أنظمة اللغة
@@ -44,6 +45,7 @@
- [نظام الأنواع وفاحص الأنواع](systems/types.md)
- [نظام الأخطاء والتشخيص](systems/errors.md)
- [الدوال المضمنة والوحدات](systems/builtins.md)
+- [محرّك تخطيط SadUI والمحاذاة المتقاطعة RTL](systems/sadui-layout.md)
# الجزء السابع · المساهمة والحوكمة
diff --git a/src/backend/crypto-unification.md b/src/backend/crypto-unification.md
new file mode 100644
index 0000000..b857ef7
--- /dev/null
+++ b/src/backend/crypto-unification.md
@@ -0,0 +1,107 @@
+# دراسة حالة: توحيد هاش/شفّر/فك_تشفير بين المحرّكين
+
+مثال متكامل على **إزالة تباعُد** بين المفسّر والمترجم (لا إضافة ميزة جديدة): دالّتا
+`هاش`/`شفّر`/`فك_تشفير` في وحدة `تأكيدات` كانتا مُنفَّذتين مرّتين بخوارزميّتين
+مختلفتين تمامًا — والمترجم كان يملك **نسخة ثالثة** منفصلة لهدف Android لم يمسّها أحد.
+المرجع اللغويّ للمستخدم في
+[sadlang-docs](https://github.com/sadlang/sadlang-docs/blob/main/src/language/security.md)؛
+هذه الصفحة للمساهم في **التنفيذ**.
+
+> **المبدأ الأهمّ:** التوحيد بين المحرّكين لا يعني «اختيار نسخة والحذف» فقط —
+> يعني أيضًا **البحث عن كل نسخة**. النسخة الثالثة في مُصدِّر Android كانت لتبقى
+> متباعدة لو لم تكشفها مراجعة مستقلّة قبل الدفع (انظر «الفخّ» أدناه).
+
+## الوضع قبل التوحيد
+
+```mermaid
+flowchart TD
+ MOD["وحدة تأكيدات: هاش / شفّر / فك_تشفير"]
+ MOD --> INT["المفسّر
builtin_module_assertions.cpp
SHA-256 + SHA-256-CTR حقيقيّ"]
+ MOD --> CMP["المترجم (سطح مكتب/Windows/Linux)
sad_embedded_runtime.c
FNV-1a + XOR بسيط"]
+ MOD --> AND["المترجم (هدف Android)
compiler_driver_android_linker.cpp
نسخة ثالثة منفصلة: FNV-1a"]
+ DEAD["stdlib/crypto/*
Hash/HMAC/AES/Base64 عبر OpenSSL"] -.->|"لا مستهلك — ميتة"| MOD
+```
+
+ثلاث حقائق متزامنة سبّبت الالتباس:
+1. **`هاش("نفس النص")` يُعطي قيمتين مختلفتين** حسب المحرّك المُشغِّل — FNV-1a
+ (عدد صحيح) في المترجم مقابل SHA-256 حقيقيّ (نصّ ست عشريّ) في المفسّر.
+2. **`شفّر`/`فك_تشفير` غير متبادلين عبر المحرّكين** — XOR بسيط في المترجم لا
+ يفكّه SHA-256-CTR الذي شفّر به المفسّر، والعكس.
+3. **`stdlib/crypto/` كانت تبدو الحلّ الصحيح** (OpenSSL كامل: Hash/HMAC/AES/
+ Base64) لكن بلا أيّ مستهلك في المفسّر أو المترجم — بُنِيت واختُبِرت (هدف
+ CMake `crypto_tests`) دون أن تُربَط بأيّ مسار تنفيذ فعليّ.
+
+## القرار: SHA-256 هو المصدر الحقيقيّ، لا OpenSSL
+
+الخيار الأول (ربط `stdlib/crypto` بالمترجم) يعمّق الانقسام بدل إغلاقه: لا يزال
+يترك FNV-1a قائمًا في مسارات لا تستورد `stdlib/crypto` صراحةً، ويكسر **هدف
+الوضع الحرّ** (freestanding) الذي لا يمكنه الربط بـOpenSSL أو أيّ مكتبة نظام
+تشغيل مضيف — قيد قائم أصلًا على
+[`tools/compiler/runtime/sad_embedded_runtime.c`](https://github.com/sadlang/s-programming-language/blob/dev/tools/compiler/runtime/sad_embedded_runtime.c)
+(راجع تعليقات SEM019 فيه). القرار: **حذف `stdlib/crypto` كليًّا**، ونقل خوارزميّة
+SHA-256/SHA-256-CTR **الذاتيّة التنفيذ** (self-rolled، بلا اعتماديّات) من المفسّر
+إلى وقت تشغيل المترجم — لا العكس.
+
+## التنفيذ عبر الطبقات
+
+| الطبقة | قبل | بعد |
+|---|---|---|
+| **المفسّر** ([`builtin_module_assertions.cpp`](https://github.com/sadlang/s-programming-language/blob/dev/interpreter/src/builtins/builtin_module_assertions.cpp)) | SHA-256 حقيقيّ (بلا تغيير — هو المرجع) | — |
+| **وقت تشغيل المترجم** ([`sad_embedded_runtime.c`](https://github.com/sadlang/s-programming-language/blob/dev/tools/compiler/runtime/sad_embedded_runtime.c)) | `sad_security_hash` يُرجع `long long` (FNV-1a)؛ XOR بسيط | `sad_sha256_raw`/`sad_sha256_rotr` + `sad_security_hash` يُرجع `const char *` (سلسلة ست عشريّة 64 حرفًا)؛ CTR بنفس بنية nonce+عدّاد للمفسّر |
+| **واجهة SIR الأماميّة** ([`builtins_security.cpp`](https://github.com/sadlang/s-programming-language/blob/dev/compiler/src/frontend/builders/builtins_security.cpp)) | نوع الإرجاع `SadTypeKind::Integer` لـHASH | `SadTypeKind::String` |
+| **مولِّد LLVM** ([`security_builtins_ops.cpp`](https://github.com/sadlang/s-programming-language/blob/dev/compiler/src/backend/llvm/builders/builtins/security_builtins_ops.cpp)) | توقيع `sad_security_hash`: `(i8*) -> i64` | `(i8*) -> i8*` |
+| **مُصدِّر Android** ([`compiler_driver_android_linker.cpp`](https://github.com/sadlang/s-programming-language/blob/dev/tools/compiler/compiler_driver_android_linker.cpp)) | نسخة ثالثة FNV-1a منفصلة تمامًا | نفس SHA-256 (`sad_sha256_rotr`/`sad_sha256_raw`/`sad_security_hash`) — هذا الهدف لا يملك `sad_security_encrypt`/`decrypt` أصلًا |
+
+`sad_security_encrypt`/`decrypt` نُقِلا بنفس بنية المفسّر: مقطع `nonce` عشوائيّ
+8 بايت في بداية الناتج، وكل كتلة 32 بايت تُخفى بـ`SHA-256(مفتاح ‖ nonce ‖ عدّاد)`
+كتيّار مفاتيح XOR.
+
+```mermaid
+flowchart LR
+ SRC["هاش(نص) / شفّر(نص، مفتاح)"] --> INTP["المفسّر: تقييم مباشر
sha256 lambda"]
+ SRC --> SIR["المترجم: CALL sad_security_*
(SadTypeKind::String الآن)"]
+ SIR --> RT["sad_embedded_runtime.c
sad_sha256_raw مطابق للمفسّر"]
+ INTP -.->|"تكافؤ حرفيّ + تبادليّة عابرة للمحركين"| RT
+```
+
+## الفخّ: نسخة ثالثة كادت تفوت المراجعة
+
+التغيير الأوّلي مسّ `sad_embedded_runtime.c` فقط (المسار المشترك لسطح
+المكتب/Windows/Linux). مراجعة مستقلّة قبل الدفع (وفق سياسة الفريق: مراجع مستقلّ
+إلزاميّ قبل أيّ `git push`) كشفت أنّ
+[`compiler_driver_android_linker.cpp`](https://github.com/sadlang/s-programming-language/blob/dev/tools/compiler/compiler_driver_android_linker.cpp)
+يحمل **نسخة كاملة منفصلة** من دوال وقت التشغيل لهدف Android — بما فيها FNV-1a
+القديمة — لم يكن `grep` الأوّلي على `sad_security_hash` عبر شجرة الكود قد
+شملها لأنّها بحث لم يُعَد على كامل الشجرة. الدرس: **البحث عن كل نسخة يسبق
+حذف/توحيد أيّ منطق مكرَّر** — لا يكفي تتبّع نقطة تسجيل الدالّة المضمنة الواحدة
+(`compiler_strategy: RUNTIME_CALL` في SoT) لأنّ نقطة **الربط الفعليّ**
+(linker) قد تتفرّع حسب الهدف.
+
+كما كُشِف تسريب أمنيّ ثانويّ في نفس المراجعة: تشفير/فكّ التشفير كانا يستعملان
+مخزنًا ثابت الحجم على المكدس (`unsigned char input[8+8+256]`) يقتطع المفاتيح
+الأطول من 256 بايت **صامتًا** بدل رفضها أو دعمها — أُصلح بتخصيص ديناميكيّ
+(`malloc(klen + 16)`).
+
+## نقطة الحسم: هل يُذكَر خطأ فكّ_تشفير على مدخل غير صالح؟
+
+بقي تباعُد واحد **موثَّق عمدًا لا مُصلَح**: عند مدخل ست عشريّ غير صالح، المفسّر
+يرمي استثناء لغويًّا قابلًا للالتقاط بـ`حاول`/`امسك`، بينما وقت تشغيل المترجم
+(دالّة C خالصة) يطبع رسالة على `stderr` ويُعيد النصّ الأصليّ دون رمي استثناء —
+لأنّ ربط دالّة C خارجيّة بآليّة الاستثناءات المبنيّة على LLVM
+([`exception_ops.cpp`](https://github.com/sadlang/s-programming-language/blob/dev/compiler/src/backend/llvm/builders/arithmetic/exception_ops.cpp))
+تغيير معماريّ أعمق من نطاق التوحيد الحاليّ. مُوثَّق في وصف `DECRYPT` بـ
+[`language-truth/builtins/assertions.yaml`](https://github.com/sadlang/s-programming-language/blob/dev/language-truth/builtins/assertions.yaml)
+وفي `RISK.md` الخاصّ بقسم اختبارات المكتبة القياسيّة، بدل إخفائه خلف اختبار
+لا يغطّي مسار الخطأ.
+
+## الاختبار (تكافؤ مزدوج)
+
+`tests/behavior/sections/09_المكتبة_القياسية/04_تشفير/` — أربعة ملفّات:
+شعاعات FIPS 180-4 الرسميّة لـ`هاش("")`/`هاش("abc")`، تبادليّة `شفّر`/`فك_تشفير`
+عبر نصوص عربيّة/مختلطة/متعدّدة الكتل، شعاع ثابت مُسجَّل يدويًّا كمرساة انحدار،
+واختبار مفتاح أطول من 256 بايت (يرصد رجوع باغ الاقتطاع الصامت). كلّ ملفّ يُشغَّل
+عبر `sad-run.exe` **و**`sadc.exe` ويُقارَن الناتج حرفيًّا (ADR-03) — هذا ما
+يضمن ألّا يعود التباعُد.
+
+---
+**اقرأ بعده:** [دوال مضمنة ووحدات](../systems/builtins.md) · [نظام معالجة الأخطاء](../systems/errors.md).
diff --git a/src/systems/builtins.md b/src/systems/builtins.md
index c9051b7..e48e3b8 100644
--- a/src/systems/builtins.md
+++ b/src/systems/builtins.md
@@ -35,4 +35,5 @@ shared/builtins/generated/builtin_registry_generated.h ← مُولَّد
> التفاصيل في مهارة `sad-lang-dev` (`references/builtins-system.md`).
---
-**اقرأ بعده:** [سير عمل الفروع](../contributing/workflow.md).
+**اقرأ بعده:** [دراسة حالة: توحيد هاش/شفّر/فك_تشفير](../backend/crypto-unification.md) ·
+[سير عمل الفروع](../contributing/workflow.md).
diff --git a/src/systems/sadui-layout.md b/src/systems/sadui-layout.md
new file mode 100644
index 0000000..627529f
--- /dev/null
+++ b/src/systems/sadui-layout.md
@@ -0,0 +1,58 @@
+# محرّك تخطيط SadUI والمحاذاة المتقاطعة (RTL)
+
+> **الغرض:** شرح محرّك تخطيط واجهات SadUI (`LayoutEngine`) ومنظومة المحاذاة
+> المتقاطعة مع دعم **RTL** الأصيل — كيف تُوضَع أبناء الحاويات، وخاصّيّة «محاذاة»،
+> والهامش والأوزان، ومصدر حقيقة مفاتيح الخصائص.
+
+إطار SadUI **عربيّ RTL-أوّلًا**: الافتراض `LayoutDirection::RTL` في كلّ الطبقات.
+لذا يبدأ محتوى الشاشة من **اليمين** لا اليسار.
+
+## المرحلتان المدموجتان
+
+محرّك التخطيط (`features/graphics/core/src/layout.cpp`) يجمع منطقَي **القياس**
+و**الترتيب** في **تمريرة تنازليّة واحدة**: `layout()` يستدعي `arrange()` من الجذر
+للأوراق، و`arrange` يستدعي `measure()` عند كلّ مستوًى حسب الحاجة.
+
+- **المحور الرئيسيّ:** للعمود عموديّ (تكديس رأسيّ)، وللصفّ أفقيّ.
+- **المحور المتقاطع:** المحور الآخر — للعمود أفقيّ (اتّجاهيّ RTL/LTR)، وللصفّ
+ عموديّ (غير اتّجاهيّ).
+
+## خاصّيّة «محاذاة» المتقاطعة
+
+| الوضع | العمود (RTL) | العمود (LTR) | الصفّ |
+|---|---|---|---|
+| `بداية` (افتراضيّ) | اليمين | اليسار | الأعلى |
+| `وسط` | توسيط | توسيط | توسيط عموديّ |
+| `نهاية` | اليسار | اليمين | الأسفل |
+| `تمدّد` | يملأ العرض | يملأ العرض | يملأ الارتفاع |
+
+- **تمدّد** يجعل الابن يملأ المحور المتقاطع كاملًا فيتخطّط هو وأحفاده بالمقاس
+ الكامل؛ الابن ذو **المقاس الصريح** في ذلك المحور يفوز على التمدّد (كـ
+ `align-items: stretch` في CSS).
+- **حدّ:** «محاذاة» يُكرِّمها **العمود والصفّ حصرًا**؛ الشبكة/المكدّس/الالتفاف/
+ التمرير لها تموضع RTL مبيَّت خاصّ لكنّها تتجاهلها.
+
+## الهامش والحشو والأوزان
+
+- **حشو:** إزاحة داخليّة تُقلّص منطقة المحتوى من الجانبين.
+- **هامش:** إزاحة خارجيّة تُقحِم المحتوى `[هامش+حشو، العرض−هامش−حشو]`، ويُخصم
+ من قيود الأبناء فلا يتجاوز الابن مالئ-المحور فجوة الهامش.
+- **وزن (وزن/flex):** حصّة الابن من المساحة المتبقّية على المحور الرئيسيّ؛ توزيعه
+ يحترم المقاس الصريح للحاوية (إن وُجد فالتوزيع ضمنه، وإلّا يتمدّد ليملأ القيد).
+
+## مصدر حقيقة مفاتيح الخصائص (SoT)
+
+كلّ مفتاح خاصّيّة (نحو «محاذاة»/«حشو»/«عرض») معرَّف في
+`language-truth/ui_props.yaml` (٨٢ مفتاحًا)، يُولَّد منه
+`sad_ui/prop_keys.h` (ثوابت `sad::ui::props::`) عبر `x.py gen`. **لا سلسلة
+مفتاح خام في كود الرسوميّات** — يُقرأ المفتاح دائمًا عبر الثابت المولَّد:
+
+```cpp
+node.findProperty(props::ALIGN) // ✓ لا findProperty("محاذاة")
+```
+
+يحرسه `check_no_raw_props.py` + `check_ui_props_consistency.py` ضمن
+`x.py gen --check` (محلّيًّا + CI)، وworkflow `props-literals-lint.yml`.
+
+> التفصيل المعماريّ الكامل (مع الأمثلة والرسوم) في مستودع اللغة:
+> `docs/architecture/sadui-layout-alignment.md`.
diff --git a/sync/sources.yaml b/sync/sources.yaml
index ab212de..793136d 100644
--- a/sync/sources.yaml
+++ b/sync/sources.yaml
@@ -91,6 +91,20 @@ chapters:
- language-truth/builtins
- interpreter/src/builtins
+ - file: src/systems/sadui-layout.md
+ sources:
+ - features/graphics/core/src/layout.cpp
+ - features/graphics/core/include/sad_ui/prop_keys.h
+ - language-truth/ui_props.yaml
+ - scripts/codegen/gen_ui_props.py
+
+ - file: src/backend/crypto-unification.md
+ sources:
+ - compiler/src/frontend/builders/builtins_security.cpp
+ - compiler/src/backend/llvm/builders/builtins/security_builtins_ops.cpp
+ - interpreter/src/builtins/builtin_module_assertions.cpp
+ - language-truth/builtins/assertions.yaml
+
- file: src/sot/philosophy.md
sources:
- language-truth/_schemas