From 8ac7b437a4c071bfab0c306b8e4ce7015bd368b9 Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Mon, 17 Aug 2026 02:45:49 -0400 Subject: [PATCH 1/2] =?UTF-8?q?docs(arabic):=20README.ar.md=20=E2=80=94=20?= =?UTF-8?q?the=20Arabic=20entry=20point,=20terminology=20exact=20(#290)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.ar.md | 102 +++++++++++++++++ README.md | 2 + tests/test_arabic_readme.py | 215 ++++++++++++++++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 README.ar.md create mode 100644 tests/test_arabic_readme.py diff --git a/README.ar.md b/README.ar.md new file mode 100644 index 00000000..4dd5a147 --- /dev/null +++ b/README.ar.md @@ -0,0 +1,102 @@ +
+ +# كيل (keel) + +**العربية** | [English](README.md) + +**كيل محرّكُ امتثالٍ شرعيٍّ قابلٌ للتدقيق، لتداول العملات المشفّرة الفوري (Spot)** — +سككُ أمانٍ حتميّةٌ لا يمكن تجاوزها، وفرزُ أصولٍ موثَّقٌ يرفض عند غياب الدليل، +وتقنينُ القبض الحُكميّ (§65.4) فحصًا قابلًا للتنفيذ — وفوق ذلك كلّه وكيلُ تداولٍ +آليٌّ مرجعيٌّ لمنصّة Coinbase. كثيرون لديهم بوتُ تداول؛ لكن لا أحد تقريبًا يملك +هذه الآليّات الامتثالية، وهي الجزء الذي يستحقّ القراءة. + +**النتيجة الصادقة، نقولها نحن أوّلًا:** لا توجد عائلة قواعدٍ مُصدَّرة تحقّق ربحًا +صافيًا عند رسوم الآخذ (taker) المدفوعةِ فعليًا على هذه المنصّة — فالتكلفة هي القيد +الحاكم، وتقاطُعُ المعاملات والرسوم الممكنِ فارغٌ تحت تنفيذٍ مطابقٍ للإنتاج +([سجلّ التجربة](docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md)). +الغاية من هذا المشروع هي آليّاتُ الإنفاذ والقياسُ الصادقُ لما يمرّ عبرها، لا +ادّعاءُ تفوّقٍ في الأداء. الزائر الذي يكتشف ذلك بنفسه يشعر بالخداع؛ أمّا من +نُبِّه مسبقًا فيقرؤه أمانةً ودقّةً. + +> **كيل ليس محرّكَ فتاوى؛ إنه محرّكُ إنفاذٍ لحكمٍ شرعيٍّ أنت من يزوّده.** كيل لا +> يستنبط تصنيفًا شرعيًّا من بيانات السوق أبدًا. أنت تسجّل التصنيف — بمصدرٍ واسمٍ +> منسوبٍ إليه (`keel assets attest`) — وكيل ينفّذه حتميًا، رافضًا كلَّ ما ليس +> موثَّقًا. الحُكمُ يسكن توثيقك لا الشيفرة، ولذلك يحصل مُشغّلان يتبعان مذهبين +> مختلفين على إجابتين مختلفتين من الشيفرة نفسها، بتصميمٍ مقصود. انظر +> `CONTRIBUTING.md` لمعرفة ما يعنيه ذلك لطلبات الدمج. +> +> *(بالإنجليزية: "keel is not a fatwa engine. It is an enforcement engine for a ruling +> you supply.")* + +**لم تَجرِ أيُّ مراجعةٍ علميةٍ شرعيةٍ للأساس الفقهيّ لكيل.** الأساسُ قراءةٌ موثَّقةُ +المصادر لمُشغّلٍ واحد — نُشرت في [`docs/fiqh-basis.md`](docs/fiqh-basis.md) تحديدًا +ليُمكن تدقيقها والاعتراض عليها — وكلُّ مُشغّلٍ مسؤولٌ عن توثيقاته الخاصّة. + +كيل أداةٌ شخصية، ليست نصيحةً مالية وليست فتوى ولا نصيحةً شرعية — انظر التنبيهات في +أسفل هذه الصفحة. + +## جرّبه في خمس دقائق + +كلُّ ما هنا للقراءة فقط ومن جهة التداول الافتراضي (paper): لا أموال، ولا شيء في هذا +المسار يمكنه تقديم أمر شراء. مُتحقَّقٌ منه على نسخةٍ نظيفة من المستودع. تحتاج +[uv](https://docs.astral.sh/uv/) و**مفتاح Coinbase Developer Platform (CDP) مجانيًّا +للقراءة فقط** — تُجلَب بيانات الشموع عبر العميل المُصادَق، لذا يفشل الأمر +`keel fetch` من دون مفتاحٍ بخطأ `AuthenticationError`؛ نقولها مقدَّمًا كي لا تكون +مفاجأةً في الخطوة الرابعة. + +```bash +git clone https://github.com/CodeGateSoftware/keel.git && cd keel +uv sync --all-extras --dev # أي Python من 3.11 فما فوق (المستودع يُطوَّر على 3.14) +cp .env.example .env # ضع مفتاح وسرّ CDP فيه — لبيانات السوق فقط +uv run keel rules seed # سجّل عائلات القواعد كمرشّحات +uv run keel fetch # اجلب تاريخ الشموع للقائمة المسموحة الافتراضية +uv run keel simulate --years 1 --skip-within-cap +``` + +يعيد الأمر `keel simulate` تشغيل القواعد الحقيقية حتميًّا فوق التاريخ المجلوب، +ويقارنها بمقياس DCA، ويكتب تقرير GO-LIVE أو TRAIN-MORE مع البوابات وأرقامها. على +القواعد الافتراضية سيخبرك على الأرجح **TRAIN MORE** ويسمّي البوابات التي لم تُجَز — +فهذا هو المحرّك يعمل، لا يتعطّل؛ الأمانةُ هي الميزة. الخطوات التالية — ترقية قاعدة +عبر البوابة (`keel rules promote`، التي ترفض الترقية من دون فحص فرطِ مواءمة)، وتشغيل +الوكيل الافتراضي (`keel agent`، فالوضع الافتراضي هو paper)، ثم أوّل أمرٍ حقيقيٍّ +تحت إشرافك — كلّها في [`docs/go-live-runbook.md`](docs/go-live-runbook.md) (بالإنجليزية). + +## مصطلحات هذه الصفحة + +| المصطلح | بالإنجليزية | معناه هنا | +| --- | --- | --- | +| الربا | riba | زيادةٌ مشروطةٌ على أصل المال؛ يرفضها الفرز في محور `pays_yield` | +| القبض | qabd | حيازةُ العين وأخذُها؛ حُكميٌّ إذا قامت القرينةُ مقامَ الحيازة، وهو أساس السكّة 17 | +| العين | 'ayn | شيءٌ مملوكٌ موجود، لا التزام في ذمّة | +| الدَّين | dayn | التزامٌ في ذمّة الغير؛ لا يقبلُه الفرزُ لقائمة المسموح | +| الغرر | gharar | جهالةٌ مؤثّرةٌ في المعاوضة؛ يعالجها التصميمُ بالرفض الحتميّ عند الجهل | + +## نطاق هذه الصفحة + +هذه الصفحة نقطةُ دخولٍ عربية: ما هو كيل، ونتيجتُه المقيسة، وحدودُه، وكيف تجرّبه. +الوثائق الكاملة — سجلّات التجارب، وكُتب التشغيل، وأساسُ الفقه (`docs/fiqh-basis.md`)، +ودليلُ المساهمة (`CONTRIBUTING.md`) — **بالإنجليزية** وتبقى كذلك؛ هذه الصفحة ليست +وعدًا بترجمة كل شيء، بل بابٌ تدخل منه. صيغت المصطلحات وفق الاستعمال الشرعيّ +المستقرّ أعلاه، وإن رأيت تحسينًا في صياغةٍ أو مصطلحٍ فأهلًا بك في +[Discussions](https://github.com/CodeGateSoftware/keel/discussions) — تصحيحُ اللغة +والاصطلاح فيها مرحَّبٌ دائمًا. + +## أسئلة ومساهمة + +- **الأسئلة والأفكار ونقاش التصنيف** → + [Discussions](https://github.com/CodeGateSoftware/keel/discussions)، وفيها فئةٌ + مخصّصة لأسئلة الامتثال والتصنيف. +- **المساهمة** → [`CONTRIBUTING.md`](CONTRIBUTING.md) (بالإنجليزية) — معيارُ التوثيق + والبواباتُ التي يجب أن يجتازها أيّ طلب دمج. للقادمين الجدد: ابحث عن المسائل + الموسومة `good first issue`. +- **السلوك** → [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) (بالإنجليزية). +- **أيُّ ما قد يجعل كيل يسلك سلوكًا خاطئًا** → [`SECURITY.md`](SECURITY.md) + (بالإنجليزية)، وبشكلٍ خاصّ — سكّةٌ يمكن تجاوزُها ليست علةً فحسب بل ثغرةً أمنية. + +## تنبيهات + +كيل أداةٌ شخصية، ليست نصيحةً مالية وليست فتوى ولا نصيحةً شرعيةً. استشر مستشارًا +ماليًّا مؤهَّلًا وعالِمًا موثوقًا قبل أيّ تداول. أنت وحدك المسؤول عن قراراتك في +التداول. مرخَّص بموجب [Apache-2.0](LICENSE). + +
diff --git a/README.md b/README.md index 62189019..ca82ab41 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # keel +**English** | [العربية](README.ar.md) + **keel is an auditable Shariah-compliance engine for spot crypto trading** — deterministic safety rails, attested asset screening that fails closed, and §65.4 *qabd* (constructive possession) encoded as an executable check — with a reference auto-trading agent built on top diff --git a/tests/test_arabic_readme.py b/tests/test_arabic_readme.py new file mode 100644 index 00000000..bccd9654 --- /dev/null +++ b/tests/test_arabic_readme.py @@ -0,0 +1,215 @@ +"""The Arabic entry point: README.ar.md, and the switchers that bind it (#290). + +A large share of keel's intended audience reads Arabic, and #290's point is that an Arabic +entry point is a signal the project means to serve that audience rather than merely permit +it. The issue is equally clear about the failure mode: the vocabulary of Islamic finance -- +riba, qabd, 'ayn, dayn, gharar -- has precise, established Arabic renderings, and a machine +translation will get them subtly wrong, which in this domain is not a style problem but a +trust problem. + +So this file pins the Arabic README to the same three facts the English first screen pins +(what keel is, the honest measured result, the not-a-fatwa-engine boundary), pins the +quickstart commands verbatim (commands are language-neutral -- an Arabic reader must be +able to run the identical path), pins the five terms in their established renderings, and +pins the scope statement: the full docs remain English; this is the entry point, not a +promise to translate everything. The boundary's English original is pinned INSIDE the +Arabic document too, so the translation and its source travel together and drift is +detectable from either side. Terminology was authored to the established renderings; the +document itself invites correction via Discussions, which is the honest form of "reviewed +by a native speaker" available to this repo today. +""" + +from __future__ import annotations + +import re +from pathlib import Path + +_ROOT = Path(__file__).resolve().parents[1] + +#: The Arabic entry point (#290): a sibling of README.md, discoverable from it. +_AR = "README.ar.md" + +#: The boundary, in Arabic, pinned verbatim -- the same house pattern as +#: test_governance.py's English `_BOUNDARY`, so neither language can drift alone. +_BOUNDARY_AR = "كيل ليس محرّكَ فتاوى؛ إنه محرّكُ إنفاذٍ لحكمٍ شرعيٍّ أنت من يزوّده" + +#: The no-scholarly-review stance (#289), stated in Arabic with the same bluntness. +_NO_REVIEW_AR = "لم تَجرِ أيُّ مراجعةٍ علميةٍ شرعيةٍ للأساس الفقهيّ لكيل" + +#: The honest result, in Arabic: no shipped rule family is net-positive at the taker fee +#: actually paid. Pinned as a distinctive clause, not a word, so a paraphrase cannot +#: soften it into vagueness. +_HONEST_AR = "لا توجد عائلة قواعدٍ مُصدَّرة تحقّق ربحًا صافيًا" + +#: The scope statement's load-bearing half: this page is the entry point, not a promise +#: to translate everything. +_SCOPE_AR = "ليست وعدًا بترجمة كل شيء" + +#: The experiment record the honest result links -- the same file test_readme.py pins, +#: asserted here too so the Arabic page can never cite a record renamed away. +_EXPERIMENT_RECORD = "docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md" + +#: The five terms #290 names as the ones a machine translation gets subtly wrong. Each +#: must appear in the Arabic README in its established rendering -- the glossary table is +#: where they are defined, so an Arabic reader meets them defined, not assumed. +_TERMS = ("الربا", "القبض", "العين", "الدَّين", "الغرر") + + +def _unwrapped(text: str) -> str: + """Join markdown wrapping: drop blockquote markers, then collapse all whitespace.""" + return " ".join(re.sub(r"(?m)^\s*>\s?", "", text).split()) + + +def _read(relative: str) -> str: + """A repo file's text; empty until it exists, so a red run FAILS rather than errors.""" + path = _ROOT / relative + return path.read_text() if path.is_file() else "" + + +def test_the_arabic_readme_exists_and_declares_rtl(): + """An Arabic reader gets a real page, rendered right-to-left, not a stub. + + GitHub renders the `
` wrapper (blank-line delimited so the markdown + inside still renders); without it the Arabic text is bidi-reordered per line against a + left-aligned frame, which reads as an afterthought -- the exact signal #290 says not + to send. + """ + text = _read(_AR) + assert '
' in text, ( + f"{_AR} must wrap its content in
so GitHub renders the page " + "right-to-left" + ) + + +def test_both_readmes_carry_the_language_switcher(): + """The switcher is two-sided: from English to Arabic, and back. + + A link that exists in one direction only is a door that locks behind the reader; the + Arabic page must be discoverable from README.md's first lines, and must lead back. + """ + en = _unwrapped(_read("README.md").split("\n## ", 1)[0]) + ar = _unwrapped(_read(_AR).split("\n## ", 1)[0]) + assert "README.ar.md" in en, ( + "README.md's first screen must link README.ar.md -- the Arabic entry point is " + "discoverable where every reader starts" + ) + assert "README.md" in ar, ( + f"{_AR}'s first screen must link back to README.md -- the switcher is two-sided" + ) + + +def test_the_boundary_is_stated_in_arabic_with_its_english_original(): + """The not-a-fatwa-engine boundary, translated precisely, source quoted alongside. + + The Arabic sentence is pinned verbatim, and the English original is pinned INSIDE the + Arabic document: a translation whose source is not present cannot be checked against + it, and this boundary is the one sentence the project cannot afford to have drift + between its two languages. + """ + text = _unwrapped(_read(_AR)) + assert _BOUNDARY_AR in text, ( + f"{_AR} must state the boundary in Arabic, pinned verbatim: {_BOUNDARY_AR!r}" + ) + assert ( + "keel is not a fatwa engine. It is an enforcement engine for a ruling you supply." + in text + ), ( + f"{_AR} must quote the boundary's English original alongside its translation, so " + "the two languages' statements are checkable against each other" + ) + + +def test_the_no_scholarly_review_stance_is_stated_in_arabic(): + """#289's stance crosses the language barrier with its bluntness intact. + + A translation that softens 'no scholarly review has occurred' into something more + comfortable would be the overstated claim #289 warns about, in different clothes. + """ + assert _NO_REVIEW_AR in _unwrapped(_read(_AR)), ( + f"{_AR} must state the no-scholarly-review stance plainly: {_NO_REVIEW_AR!r}" + ) + assert "docs/fiqh-basis.md" in _read(_AR), ( + f"{_AR} must link docs/fiqh-basis.md -- the Arabic reader is owed the same " + "auditable basis the English reader gets" + ) + + +def test_the_honest_result_is_stated_in_arabic_and_links_the_record(): + """The measured result crosses over too, with its evidence. + + The honest result is the project's credibility play ('stated by us first'); an Arabic + entry point that omitted it, or stated it without the record, would read as marketing + to exactly the audience most likely to check. + """ + text = _unwrapped(_read(_AR)) + assert _HONEST_AR in text, ( + f"{_AR} must state the honest result in Arabic, pinned verbatim: {_HONEST_AR!r}" + ) + assert _EXPERIMENT_RECORD in text, ( + f"{_AR} must link the experiment record ({_EXPERIMENT_RECORD}) behind the claim" + ) + assert (_ROOT / _EXPERIMENT_RECORD).is_file(), ( + "the experiment record the Arabic page cites no longer exists -- update the link" + ) + + +def test_the_quickstart_commands_are_verbatim(): + """Commands are language-neutral: the Arabic reader runs the identical path. + + The quickstart is pinned to the same commands test_readme.py pins, because a step + 'translated' into a variant that behaves differently is a step that fails for the + reader who trusted the Arabic page. The CDP key caveat must survive translation too. + """ + text = _unwrapped(_read(_AR)) + for command in ( + "uv sync --all-extras --dev", + "keel rules seed", + "keel fetch", + "keel simulate --years 1 --skip-within-cap", + ): + assert command in text, f"{_AR}'s quickstart must include the command {command!r}" + assert "CDP" in text, ( + f"{_AR} must keep the CDP key caveat -- `keel fetch` fails without a key, and the " + "Arabic reader must learn that before step four, not at it" + ) + + +def test_the_five_terms_appear_in_their_established_renderings(): + """riba, qabd, 'ayn, dayn, gharar -- defined in the document, not assumed. + + #290 names these five as the vocabulary a machine translation gets subtly wrong; the + Arabic README carries a glossary that gives each its established rendering with the + English term beside it, so the entry point teaches the vocabulary it uses. + """ + text = _read(_AR) + for term in _TERMS: + assert term in text, ( + f"{_AR} must use and define the established rendering of {term!r} -- the " + "glossary is where an Arabic reader meets these terms defined" + ) + + +def test_the_scope_is_stated_entry_point_not_translation_promise(): + """The Arabic page says what it is: a door, not a promise. + + The full docs remain English, and saying so in the page itself is the difference + between an entry point and an implied commitment the project cannot keep. + """ + text = _unwrapped(_read(_AR)) + assert _SCOPE_AR in text, ( + f"{_AR} must state its scope: the entry point, {_SCOPE_AR!r}" + ) + assert "بالإنجليزية" in text, ( + f"{_AR} must say plainly that the full documentation remains in English" + ) + + +def test_disclaimers_are_stated_in_arabic(): + """Not financial advice, not religious advice -- in the reader's language too.""" + text = _unwrapped(_read(_AR)) + assert "ليست نصيحةً مالية" in text, ( + f"{_AR} must carry the not-financial-advice disclaimer in Arabic" + ) + assert "وليست فتوى" in text or "ولا نصيحةً شرعية" in text, ( + f"{_AR} must carry the not-Shariah-advice disclaimer in Arabic" + ) From 1bb43a3af906ed0c36d0d3c28f36374d251687e3 Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Mon, 17 Aug 2026 02:59:22 -0400 Subject: [PATCH 2/2] =?UTF-8?q?docs(arabic):=20review=20fixes=20=E2=80=94?= =?UTF-8?q?=20private=20disclosure,=20parameters=20disambiguated,=20droppe?= =?UTF-8?q?d=20caveats=20restored,=20RTL=20pins=20tightened?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.ar.md | 23 +++++++++++++---------- tests/test_arabic_readme.py | 14 +++++++++++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/README.ar.md b/README.ar.md index 4dd5a147..6564cf46 100644 --- a/README.ar.md +++ b/README.ar.md @@ -12,7 +12,7 @@ **النتيجة الصادقة، نقولها نحن أوّلًا:** لا توجد عائلة قواعدٍ مُصدَّرة تحقّق ربحًا صافيًا عند رسوم الآخذ (taker) المدفوعةِ فعليًا على هذه المنصّة — فالتكلفة هي القيد -الحاكم، وتقاطُعُ المعاملات والرسوم الممكنِ فارغٌ تحت تنفيذٍ مطابقٍ للإنتاج +الحاكم، وتقاطُعُ المُعامِلات (parameters) والرسوم الممكنِ فارغٌ تحت تنفيذٍ مطابقٍ للإنتاج ([سجلّ التجربة](docs/experiments/2026-08-13-restated-under-a-production-faithful-engine.md)). الغاية من هذا المشروع هي آليّاتُ الإنفاذ والقياسُ الصادقُ لما يمرّ عبرها، لا ادّعاءُ تفوّقٍ في الأداء. الزائر الذي يكتشف ذلك بنفسه يشعر بالخداع؛ أمّا من @@ -30,7 +30,9 @@ **لم تَجرِ أيُّ مراجعةٍ علميةٍ شرعيةٍ للأساس الفقهيّ لكيل.** الأساسُ قراءةٌ موثَّقةُ المصادر لمُشغّلٍ واحد — نُشرت في [`docs/fiqh-basis.md`](docs/fiqh-basis.md) تحديدًا -ليُمكن تدقيقها والاعتراض عليها — وكلُّ مُشغّلٍ مسؤولٌ عن توثيقاته الخاصّة. +ليُمكن تدقيقها والاعتراض عليها — وكلُّ مُشغّلٍ مسؤولٌ عن توثيقاته الخاصّة. وما لم +يمشِ أحدٌ هذا الطريق، فالحالةُ: غيرُ مُراجَع — والتفصيلُ في [قسم حالة المراجعة +العلمية](docs/fiqh-basis.md#scholarly-review-status). كيل أداةٌ شخصية، ليست نصيحةً مالية وليست فتوى ولا نصيحةً شرعية — انظر التنبيهات في أسفل هذه الصفحة. @@ -38,9 +40,9 @@ ## جرّبه في خمس دقائق كلُّ ما هنا للقراءة فقط ومن جهة التداول الافتراضي (paper): لا أموال، ولا شيء في هذا -المسار يمكنه تقديم أمر شراء. مُتحقَّقٌ منه على نسخةٍ نظيفة من المستودع. تحتاج -[uv](https://docs.astral.sh/uv/) و**مفتاح Coinbase Developer Platform (CDP) مجانيًّا -للقراءة فقط** — تُجلَب بيانات الشموع عبر العميل المُصادَق، لذا يفشل الأمر +المسار يمكنه تقديم أمرِ تداولٍ من أيّ نوع. مُتحقَّقٌ منه على نسخةٍ نظيفة من المستودع. +تحتاج [uv](https://docs.astral.sh/uv/) و**مفتاح API لمنصّة Coinbase Developer +Platform (CDP) مجانيًّا للقراءة فقط** — تُجلَب بيانات الشموع عبر العميل المُصادَق، لذا يفشل الأمر `keel fetch` من دون مفتاحٍ بخطأ `AuthenticationError`؛ نقولها مقدَّمًا كي لا تكون مفاجأةً في الخطوة الرابعة. @@ -57,8 +59,8 @@ uv run keel simulate --years 1 --skip-within-cap ويقارنها بمقياس DCA، ويكتب تقرير GO-LIVE أو TRAIN-MORE مع البوابات وأرقامها. على القواعد الافتراضية سيخبرك على الأرجح **TRAIN MORE** ويسمّي البوابات التي لم تُجَز — فهذا هو المحرّك يعمل، لا يتعطّل؛ الأمانةُ هي الميزة. الخطوات التالية — ترقية قاعدة -عبر البوابة (`keel rules promote`، التي ترفض الترقية من دون فحص فرطِ مواءمة)، وتشغيل -الوكيل الافتراضي (`keel agent`، فالوضع الافتراضي هو paper)، ثم أوّل أمرٍ حقيقيٍّ +عبر البوابة (`keel rules promote`، التي ترفض الترقية من دون فحص فرطِ مواءمة)، وتشغيل وكيلِ +الوضعِ الافتراضي (paper) (`keel agent`)، ثم أوّل أمرٍ حقيقيٍّ تحت إشرافك — كلّها في [`docs/go-live-runbook.md`](docs/go-live-runbook.md) (بالإنجليزية). ## مصطلحات هذه الصفحة @@ -68,7 +70,7 @@ uv run keel simulate --years 1 --skip-within-cap | الربا | riba | زيادةٌ مشروطةٌ على أصل المال؛ يرفضها الفرز في محور `pays_yield` | | القبض | qabd | حيازةُ العين وأخذُها؛ حُكميٌّ إذا قامت القرينةُ مقامَ الحيازة، وهو أساس السكّة 17 | | العين | 'ayn | شيءٌ مملوكٌ موجود، لا التزام في ذمّة | -| الدَّين | dayn | التزامٌ في ذمّة الغير؛ لا يقبلُه الفرزُ لقائمة المسموح | +| الدَّين | dayn | التزامٌ في ذمّة الغير؛ لا يقبلُه الفرزُ في القائمة المسموحة | | الغرر | gharar | جهالةٌ مؤثّرةٌ في المعاوضة؛ يعالجها التصميمُ بالرفض الحتميّ عند الجهل | ## نطاق هذه الصفحة @@ -85,13 +87,14 @@ uv run keel simulate --years 1 --skip-within-cap - **الأسئلة والأفكار ونقاش التصنيف** → [Discussions](https://github.com/CodeGateSoftware/keel/discussions)، وفيها فئةٌ - مخصّصة لأسئلة الامتثال والتصنيف. + مخصّصة لأسئلة الامتثال والتصنيف — وهي مسألةٌ تُناقَش لا علةٌ برمجية، ولا يصحّ + تصنيفُها كذلك. - **المساهمة** → [`CONTRIBUTING.md`](CONTRIBUTING.md) (بالإنجليزية) — معيارُ التوثيق والبواباتُ التي يجب أن يجتازها أيّ طلب دمج. للقادمين الجدد: ابحث عن المسائل الموسومة `good first issue`. - **السلوك** → [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) (بالإنجليزية). - **أيُّ ما قد يجعل كيل يسلك سلوكًا خاطئًا** → [`SECURITY.md`](SECURITY.md) - (بالإنجليزية)، وبشكلٍ خاصّ — سكّةٌ يمكن تجاوزُها ليست علةً فحسب بل ثغرةً أمنية. + (بالإنجليزية) وبإبلاغٍ سريّ — سكّةٌ يمكن تجاوزُها ليست علةً فحسب بل ثغرةً أمنية. ## تنبيهات diff --git a/tests/test_arabic_readme.py b/tests/test_arabic_readme.py index bccd9654..12aba4da 100644 --- a/tests/test_arabic_readme.py +++ b/tests/test_arabic_readme.py @@ -75,9 +75,10 @@ def test_the_arabic_readme_exists_and_declares_rtl(): to send. """ text = _read(_AR) - assert '
' in text, ( - f"{_AR} must wrap its content in
so GitHub renders the page " - "right-to-left" + assert '
\n\n' in text and "\n\n
" in text, ( + f"{_AR} must wrap its content in
-- with blank lines after the " + "opening tag and before the closing one, or GitHub's HTML-block rule stops " + "rendering the markdown inside it -- so the page renders right-to-left" ) @@ -187,6 +188,10 @@ def test_the_five_terms_appear_in_their_established_renderings(): f"{_AR} must use and define the established rendering of {term!r} -- the " "glossary is where an Arabic reader meets these terms defined" ) + assert "| --- |" in text, ( + f"{_AR}'s glossary must be a real GFM table (header row plus '| --- |' separator), " + "not a drawing that stops rendering as a table" + ) def test_the_scope_is_stated_entry_point_not_translation_promise(): @@ -213,3 +218,6 @@ def test_disclaimers_are_stated_in_arabic(): assert "وليست فتوى" in text or "ولا نصيحةً شرعية" in text, ( f"{_AR} must carry the not-Shariah-advice disclaimer in Arabic" ) + assert "Apache-2.0" in text and "(LICENSE)" in text, ( + f"{_AR} must state the licence with its link, as the English README does" + )