Skip to content

كيف تكتبُ ملفَّ معايرةٍ لحارسِك

هذه وصفةٌ لِمَن عندَه حارسٌ يعملُ ويريدُ أن يُثبِتَ أنّه يعضّ. لِـلماذا انظرْ لماذا يُعايَرُ الحارسُ أصلًا.

الملفُّ المرجعيُّ الذي تُقاسُ عليه هذه الوصفة: scripts/codegen/calibrate_anchor_integrity.py (٦٧٤ سطرًا، ١٧ مجسًّا).

١ · شرطانِ قبلَ أن تبدأ

  • حارسُك يخرجُ بثلاثةِ رموز: 0 سليم · 1 حكمٌ صدرَ عن قياسٍ تمّ · 2 عطبُ آلةٍ (لم يُقَسْ شيء). بلا هذا التمييزِ لا تستطيعُ المِحقنةُ أن تُميِّزَ «التقطَ العطب» من «انهار».
  • حارسُك يطبعُ نصًّا مميِّزًا لكلِّ سببِ احمرار. المجسُّ يتحقّقُ من النصِّ لا من الرمزِ وحدَه، وإلّا صادقَ على احمرارٍ من سببٍ آخر.

٢ · هيكلُ المِحقنة

python
ROOT    = Path(__file__).resolve().parents[2]
GUARD   = ROOT / "scripts" / "codegen" / "check_my_guard.py"
HARNESS = Path(__file__).resolve()
RECORD  = ROOT / "scripts" / "codegen" / "calibration" / "check_my_guard.yaml"

def _run_guard() -> tuple[int, str]:
    env = dict(os.environ, PYTHONIOENCODING="utf-8", PYTHONUTF8="1")
    proc = subprocess.run([sys.executable, str(GUARD)], capture_output=True,
                          text=True, encoding="utf-8", cwd=str(ROOT), env=env)
    return proc.returncode, (proc.stdout or "") + (proc.stderr or "")

اسمُ الحارسِ في بايتاتِ المِحقنة

الحارسُ الفوقيُّ يرفضُ سجلًّا لا تذكرُ مِحقنتُه اسمَ ملفِّ حارسِه. السطرُ GUARD = ... "check_my_guard.py" أعلاه يفي بذلك. ولا تنسخْ مِحقنةً قائمةً وتُبدِّلْ مسارَها وحدَه — فذاك سجلٌّ يربطُ ملفَّين لا يمسُّ أحدُهما الآخر.

٣ · اكتُبِ المُطفِّرات

المُطفِّرُ دالّةٌ تأخذُ بايتاتِ الملفِّ وتُرجِعُ بايتاتٍ جديدة، ومعها تصريحُ أثر:

python
def _sub(old: bytes, new: bytes, residue: bool = False):
    def apply(blob: bytes) -> bytes:
        if blob is None or blob.count(old) < 1:
            raise AssertionError("المرساةُ غيرُ موجودة: %r" % old[:48])
        return blob.replace(old, new, 1)
    apply.residue = new if residue else _SELF_RED
    return apply

التصريحاتُ الأربعة:

التصريحمتى يُستعمَل
سِمةُ بايتاتٍنصٌّ مميَّزٌ يبقى في الملفِّ لو قُتِلَت التشغيلة (١٦ بايتًا فأكثر)
_CREATEDملفٌّ يُنشَأ — الدليلُ وجودُه
_SELF_REDالطفرةُ تُحمِّرُ الحارسَ بنفسِها فتلتقطُها البوّابة
_NO_TRACE(سبب)لا أثرَ دلاليًّا — ويلزمُ تعليلٌ نصّيّ

_SELF_RED دعوى لا مجّانيّة

معناها «بقاءُ الطفرةِ يُوقِفُ البوّابة». وهي كاذبةٌ إن كانت حمرةُ المجسِّ مشروطةً بأن يكونَ عدَّادٌ على سقفِه: على سقفٍ فيه فجوةٌ لا تُحمِّرُ الطفرةُ، فقتلٌ قاسٍ في منتصفِ المجسِّ يتركُها مُودَعةً والشجرةَ تُقرأُ «نظيفة». ولذلك ثمّةَ سجلُّ طيران (§٦).

٤ · اكتُبِ المجسّاتِ — والسالبةُ منها ليست ترفًا

python
PROBES = (
    ("① مرساةٌ يتيمة — وسمٌ يُسمّي قاعدةً مخترَعة",
     SEED, _sub(IF_ANCHOR, b"# @rule: gr.stmt.zz_invented"),
     1, "مرساةٌ يتيمة: 1"),

    # اختبارُ انحدارٍ — يجبُ أن يبقى أخضر
    ("⑧ نصٌّ في الجسمِ ليس مرساةً — لا شهادةَ بالذِّكر",
     SEED, _append('اطبع_سطر("@rule: gr.zz.in_body")\n'.encode("utf-8")),
     0, "مرساةٌ يتيمة (ترسو على غيرِ مُعلَن): 0"),

    ("⑨ مسبارٌ أعمى — رمزُ عطبِ آلةٍ 2",
     "scripts/codegen/check_my_guard.py",
     _sub(b'SKIP_PARTS = ("_archive",)',
          b'SKIP_PARTS = ("_archive", "behavior")', residue=True),
     2, "عيارُ الأداة:"),
)
MIN_PROBES = 3   # ولا تنزلْ تحتَ CEILING_MIN_PROBES في الحارسِ الفوقيّ

الصفُّ: (اسمٌ، ملفٌّ، طفرةٌ، رمزٌ منتظَر، نصٌّ منتظَر[، عدّاءٌ خاصّ]). واجعلْ ثلاثةَ أصنافٍ حاضرة: عطبٌ يجبُ التقاطُه، تغييرٌ مشروعٌ يجبُ ألّا يُلتقَط، ومسبارٌ أعمى يجبُ أن يُرَدَّ بالرمز ٢.

٥ · حلقةُ المجسِّ — الاستعادةُ مُتحقَّقٌ منها

python
def _probe(path, mutate, want_code, want_text, runner=None):
    target   = ROOT / path
    existed  = target.exists()
    original = target.read_bytes() if existed else None
    before   = hashlib.sha256(original).hexdigest() if existed else None
    try:
        _journal_open(path, before)
        target.write_bytes(mutate(original))
        code, out = (runner or _run_guard)()
    finally:
        if existed:
            target.write_bytes(original)
            restored = hashlib.sha256(target.read_bytes()).hexdigest() == before
        else:
            target.unlink(missing_ok=True)
            restored = not target.exists()
        if restored:
            _journal_close()
    if existed and hashlib.sha256(target.read_bytes()).hexdigest() != before:
        raise AssertionError("لم تُستعَدِ البايتاتُ في " + path)
    return (code == want_code) and (want_text in out), "رمز=%d" % code

الإغلاقُ داخلَ finally لا بعدَ الكتلة: أيُّ استثناءٍ في المجسِّ كان يتركُ سجلَّ الطيرانِ مفتوحًا، فتصيرُ كلُّ تشغيلةٍ تاليةٍ رفضًا كاذبًا على شجرةٍ نظيفة.

٦ · ثلاثُ شبكاتٍ قبلَ أوّلِ طفرة

python
dirty = _residue()          # أثرُ تشغيلةٍ لم تُنهَ + سجلُّ الطيران
if dirty: return 2          # لا يُقاسُ فوقَ أثرِ النفس

slack = _slack_bounds()     # سقفٌ فيه فجوةٌ ⇒ المجسّاتُ لا تعضُّ
if slack: return 2

if len(PROBES) < MIN_PROBES: return 2
  • الأثر يُشتقُّ من PROBES نفسِها صفًّا لكلِّ مجسٍّ لا لكلِّ مسار: الطيُّ على المسارِ كان يجعلُ مجسًّا بلا تصريحٍ يركبُ تسجيلَ أخيه في الملفِّ نفسِه فيبدو متتبَّعًا وليس كذلك.
  • سجلُّ الطيران ملفُّ JSON في مجلَّدِ .git (فلا يبلغُه git clean -xfd) يحملُ اسمَ الملفِّ وبصمتَه قبلَ الطفرة، ويُمحى بعدَ استعادةٍ مُتحقَّقٍ منها.
  • الفجوة: يُقرأُ مخرَجُ الحارسِ بحثًا عن N (السقف M)، فإن اختلفا أُوقِفَ العيارُ بمخرجٍ مُسمًّى: أنزِلِ السقفَ إلى المقيسِ ثمّ أعِدِ العيار.

٧ · أودِعِ السجلّ

bash
python scripts/codegen/calibrate_my_guard.py                        # قياسٌ بلا إيداع
python scripts/codegen/calibrate_my_guard.py --record --date=2026-09-06

--date إلزاميّ: لا يُقرأُ وقتُ النظامِ لئلّا يتغيّرَ السجلُّ بلا عمل، ولا يُودَعُ سجلٌّ ناقص. والمُخرَجُ ملفُّ YAML بهذا الشكلِ حرفًا:

yaml
version: 2
guard: scripts/codegen/check_my_guard.py
harness: scripts/codegen/calibrate_my_guard.py
guard_sha256: 5a632a5c36fb9d338ef733308ac2384b957ec6d180bace5f6a77fecd2bf0f601
harness_sha256: ff7a47561fb3e2b4794adbdea4b005e0d08baaa6ee3587ab4a33afd998cc8156
calibrated_at: 2026-09-06
probes_total: 17
probes_passed: 17
result: 17/17
probes:
  - name: "① مرساةٌ يتيمة — وسمٌ يُسمّي قاعدةً مخترَعة"
    target: tests/behavior/rules_matrix/10_statements/gr.stmt.if/basic/001_true_cmp_gt.ص
    expect_exit: 1
    expect_text: "مرساةٌ يتيمة: 1"
    role: "يجبُ أن يحمرّ"

٨ · صِلْه بالبوّابة

bash
python scripts/codegen/check_calibration_fresh.py       # يجبُ أن يرى سجلَّك
python -m pytest scripts/codegen/test_calibration_harness.py -q
python x.py gen --check

ثمّ أنزِلْ CEILING_UNCALIBRATED في check_calibration_fresh.py بمقدارِ واحد. وأودِعِ السقفَ والسجلَّ في الإيداعِ نفسِه: أُنزِلَ السقفُ مرّةً في إيداعٍ لم يحمِلِ السجلَّ، فأخفقت البوّابةُ على كلِّ استنساخٍ نظيفٍ بتشخيصٍ كاذبٍ يقولُ «حارسٌ جديدٌ يصلُ ومعه سجلُّ عيارِه».

٩ · مطبّاتٌ كلُّها وقعت فعلًا

البذرةُ التي لا يُيتِّمُها نزعُ مرساتِها

مجسٌّ ينزعُ مرساةً ليُثبِتَ نموَّ دَينِ الشهادةِ يلزمُه بذرةُ قاعدةٍ مرساتُها واحدةٌ فقط. نُزِعت مرساةُ gr.stmt.if أوّلَ مرّةٍ فبقيت القاعدةُ مشهودةً ببذورٍ أخرى ولم يعضَّ المجسّ — خللٌ في المجسِّ لا في الحارس، ولا يكشفُه إلّا أن يُقرأَ الناتجُ لا رمزُ الخروج.

نهاياتُ الأسطر

احسِبِ البصمةَ بعدَ تطبيعِ CRLF إلى LF في الطرفَين (.gitattributes يُعلِنُ *.py text eol=lf). بصمةٌ على البايتاتِ الخامِّ تُسجَّلُ على تمثيلٍ لا يملكُه المستودع، فتُحمِّرُ كلَّ استنساخٍ نظيفٍ بحمرةٍ لا علاقةَ لها بالمحتوى. واجعلْ اتّفاقَ الطرفَينِ مجسًّا لا وعدًا في تعليق.

اشتقاقُ الثوابتِ من الحارسِ لا نسخُها

لا تكتبْ في المِحقنةِ نسخةً ثانيةً من اسمِ عائلةٍ أو حدٍّ في الحارس: استوردْها منه. وإن غابت ارمِ — مرجعٌ مجهولٌ يعني مجسًّا أعمى. واجعلِ الاشتقاقَ كسولًا داخلَ دالّة: رميٌ عندَ الاستيرادِ يُوقِفُ جمعَ pytest كلَّه، فتُفقَدُ تشخيصاتُ اختباراتٍ لا صلةَ لها بالمِحقنة.

لا تُحمِّرْ بمقدارٍ مكتوبٍ باليد

_measure_baseline() يقرأُ العدَّاداتِ قبلَ أوّلِ حقن، ثمّ يُشتقُّ مقدارُ الطفرةِ منها (need = max(1, المقيس − الأرضيّة + 1)). طفرةٌ بمقدارٍ ثابتٍ تمرُّ خضراءَ صامتةً بأوّلِ هامشٍ يُفتَح، والبوّابةُ لا تُشغِّلُ المِحقناتِ فيموتُ الشاهدُ بلا صوت.

مُرخَّص بموجب رخصة MIT