كيف تجعل ملف AGENTS.md محدثاً تلقائياً باستخدام dox
هل يثق وكيل البرمجة في ملف AGENTS.md قديم ويسبب أخطاء في الكود؟ استخدم أداة dox لتوليد التوثيق مباشرة من المستودع ومراجعة التغييرات كأنها كود برمجي لضمان دقة المهام.
لماذا يصبح ملف AGENTS.md غير دقيق بعد ثلاثة أسابيع
يصبح ملف AGENTS.md قديماً لأن لا شيء يربطه بالكود المصدري. أنت تكتبه يدوياً مرة واحدة في اليوم الذي يبدو فيه المستودع بحالة معينة. بعد ذلك، يتغير مشغل الاختبارات، أو يُعاد تسمية حزمة، أو تُحذف خدمة، بينما يظل الملف يصف حالة شهر يونيو. لا يفشل أي شيء، لأن لا توجد خطوة بناء تقرأ هذا الملف.
يقرأ الوكيل (Agent) الملف ويصدقه. هذا هو الجزء الذي يكلفك الكثير. المستودع الذي لا يحتوي على AGENTS.md يجعل وكيل البرمجة يبحث في الملفات قبل اتخاذ أي إجراء. أما المستودع الذي يحتوي على ملف AGENTS.md غير دقيق، فيجعله يتوقف عن البحث لأنه يظن أنه يملك الإجابة بالفعل. ينفذ الوكيل الأمر المذكور في ملفك، فيرد الشل بـ Missing script: "test"، وهنا يبدأ الوكيل بالتخمين. غالباً ما يقوم بتعديل package.json لإضافة السكريبت الذي وعدت به في توثيقك. الملف القديم لم يفشل بصمت، بل تسبب في تعديل لم تكن تريده.
يُعد dox أحد الحلول لهذه المشكلة. هو مجموعة من القواعد المكتوبة للوكيل، تجعل تحديث التوثيق جزءاً من إتمام العمل، بحيث يتغير الملف في نفس الـ commit الذي تضمن الكود الذي جعل الملف غير دقيق.
ما هو dox وما ليس هو
dox هو ملف Markdown واحد. المستودع هو agent0ai/dox، وهو مرخّص بموجب رخصة MIT، واعتباراً من 11 أغسطس 2026، يتكون المشروع بأكمله من ملف AGENTS.md بحجم 3906 بايت، وملف README، وملف LICENSE، وصورتين. لا توجد حزمة للتثبيت ولا يوجد وقت تشغيل (runtime).
هذا الأمر مهم، لأن اسم المولد يوحي بوجود برنامج يحلل الكود الخاص بك. لا شيء يحلل الكود الخاص بك. dox هو عقد يقرؤه وكيل البرمجة الخاص بك: وكيلك هو المولد، وdox هو مجموعة التعليمات التي تخبره متى يقرأ الوثائق، ومتى يعيد كتابتها، وما هو الشكل الذي تتخذه كل وثيقة.
يحتوي الملف على عشرة أقسام، اثنان منها يقومان بالعمل. يخبر قسم "Read Before Editing" الوكيل بأن يتجول من جذر المستودع إلى كل مسار يخطط لتعديله، وأن يقرأ كل ملف AGENTS.md على طول كل مسار، في الجلسة الحالية، دون الاعتماد على الذاكرة. يخبره قسم "Update After Editing" أن كل تغيير ذي مغزى يتطلب تمريرة DOX، مما يعني أن خطوة تحديث الوثائق يجب أن تُنفذ قبل اعتبار المهمة مكتملة. تقوم هذه التمريرة بتحديث أقرب وثيقة مالكة عندما يتغير الغرض، أو الهيكل، أو سير العمل، أو الصلاحيات، أو تفضيلات المستخدم.
بقية الملف تتعلق بالشكل. يحتوي ملف AGENTS.md الفرعي على ترتيب أقسام افتراضي: الغرض (Purpose)، والملكية (Ownership)، والعقود المحلية (Local Contracts)، وتوجيهات العمل (Work Guidance)، والتحقق (Verification)، وفهرس DOX الفرعي (Child DOX Index). يحتوي الملف الجذري على قواعد المشروع ككل بالإضافة إلى فهرس DOX الفرعي للمستوى الأعلى، وهي الطريقة التي يكتشف بها الوكيل الوثائق الفرعية. "Closeout" هو قائمة التحقق التي يشغلها الوكيل في نهاية المهمة: إعادة فحص المسارات المتغيرة مقابل السلسلة، وتحديث أقرب الوثائق المالكة، وتحديث كل فهرس متأثر، وحذف التناقضات، وتشغيل التحقق الموجود، وتقديم تقرير بالوثائق التي تركها دون تغيير عمداً.
تثبيت التوثيق على commit محدد، وليس على main
لا يحتوي المستودع على أي وسوم (tags) أو إصدارات (releases)، لذا لا يوجد رقم إصدار لتثبيته. قم بتثبيت الـ commit بدلاً من ذلك. ملف AGENTS.md الحالي هو الـ commit رقم f34ec7ad1055d3393887e5a2670e8cb7320c9165، بتاريخ 1 أغسطس 2026.
mkdir -p .agent
curl -fsSL -o .agent/dox-f34ec7a.md \
https://raw.githubusercontent.com/agent0ai/dox/f34ec7ad1055d3393887e5a2670e8cb7320c9165/AGENTS.md
wc -c .agent/dox-f34ec7a.mdيجب أن يطبع wc -c القيمة 3906. وجود رقم مختلف يعني أنك لم تجلب الملف الذي يصفه هذا الدليل، لذا اقرأه قبل أن تثق به. إذا أخطأت في كتابة هاش الـ commit، فإن -f سيجعل curl يتوقف مع curl: (22) The requested URL returned error: 404 ولن يكتب أي محتوى، ثم يطبع wc -c القيمة 0. الملف المبتور أسوأ من عدم وجود ملف، لأن الوكيل سيتبع نصف عقد دون أن يعلم بذلك.
cp .agent/dox-f34ec7a.md AGENTS.md
git add AGENTS.md .agent/dox-f34ec7a.md
git commit -m "Add DOX rules (agent0ai/dox @ f34ec7a)"هذا الأمر cp مخصص لمستودع لا يحتوي على AGENTS.md بعد. إذا كان لديك ملف بالفعل، فلا تستبدله. ضع أقسام التوثيق فوق محتواك الحالي، واحتفظ بقواعدك الخاصة في الأسفل، واقرأ النتيجة مرة واحدة من البداية إلى النهاية. وثيقتان متناقضتان تنتجان وكيلاً يتبع السطر الذي قرأه أخيراً.
ثم اطلب من وكيلك، داخل المستودع، إجراء التمريرة الأولى. يوضح ملف README الصيغة الدقيقة:
Initialize DOX tree for this project now.يقوم هذا بإنشاء ملفات AGENTS.md الفرعية والفهارس التي تشير إليها. تحقق مما فعله قبل أن تصدقه:
git status --short
find . -name AGENTS.md -not -path './.git/*' | sortيجب أن يظهر كل ملف في مخرجات find ضمن فهرس توثيق فرعي (Child DOX Index) في مكان ما فوقه. الوثيقة الفرعية التي لا يذكرها أي فهرس هي وثيقة قد يغفل عنها الوكيل، لأن الفهرس هو الطريقة التي يعثر بها على الوثائق التي لا تقع مباشرة على المسار الذي يسلكه.
ما يمكن لـ dox رؤيته، وما لا يمكنه معرفته
يقرأ الوكيل الذي يبني شجرتك المستودع، لذا يمكن لأي شيء موجود في المستودع أن يدخل في الجرد: هيكل المجلدات، وملفات تعريف الحزم وملفات القفل، والسكربتات الموجودة في package.json أو Makefile أو pyproject.toml، وملفات سير عمل CI، وملفات Dockerfiles، ونقاط الدخول، وCODEOWNERS إذا كان لديك واحد. الجرد المبني من هذه المصادر يحافظ على نفسه ذاتياً بشكل حقيقي. عندما يتم نقل حزمة ما، تقوم الدورة التالية بنقل السطر الذي يصفها.
كل ما يلي هو من اختصاصك لتحديده، لأنه غير موجود في المستودع ليتم قراءته:
- سبب وجود قاعدة معينة، وهو ما يمنع الوكيل من إزالتها باعتبارها تعقيداً غير ضروري.
- أي المسارين العاملين هو المدعوم، وأيهما ينتظر الحذف.
- أي شيء خارج المستودع، مثل بيئة الاختبار (staging) أو سبب تثبيت إصدار معين من التبعيات قبل إصدارين.
- ما تخطط للقيام به في الأسبوع القادم، وهو الفرق بين ملف حالي وملف مفيد.
يعرف dox هذه الحقيقة عن نفسه. تنص قواعده الخاصة على أن توجيهات العمل (Work Guidance) يجب أن تعكس المعايير الحالية للمشروع أو تعليمات المستخدم، وأنه في حال عدم وجود أي منها بعد، يجب ترك القسم فارغاً. يجب أن يعكس التحقق (Verification) فحصاً موجوداً بالفعل، لذا في حال عدم وجود إطار عمل للاختبار في المستودع، يظل ذلك القسم فارغاً حتى يتم توفيره. الملف المُنشأ الذي يبتكر معياراً من تلقاء نفسه أسوأ من القسم الفارغ، لأن الوكيل سيقوم حينها بفرض هذا الابتكار.
أبقِ النوايا المكتوبة يدوياً خارج الجرد المُولَّد
هذا هو الفشل الذي يجعل المستخدمين يتخلون عن الوثائق المُولَّدة. تكتب فقرة تشرح أن طابور المهام يجب أن يظل بمستهلك واحد. بعد ثلاثة أسابيع، يقوم تمرير (pass) بإعادة كتابة الملف وتختفي فقرتك داخل فرق (diff) من أربعين سطراً، معظمها يعيد ترتيب أسماء الملفات، ولا يلاحظ أحد ذلك.
هناك آليتان، وأنت بحاجة لكلتيهما.
أولاً، انقل النوايا الدائمة إلى ملف مختلف. قرارات التصميم والمنطق الكامن وراءها تنتمي إلى ملف DESIGN.md مكتوب للوكيل، والملاحظات المخصصة للبشر تنتمي إلى المكان الذي تفصل فيه HUMAN.md عن AGENTS.md. عندها يحتوي AGENTS.md على الجرد والعقود المحلية، وهو الجزء الذي يجب أن يتغير بالضبط عند تغير الكود.
ثانياً، احمِ النوايا التي يجب أن تبقى داخل AGENTS.md. غلّفها بعلامات وتعامل مع الكتلة على أنها مملوكة للبشر:
## User Preferences
<!-- dox:keep start -->
The jobs queue stays single consumer. Ordering is the reason this service exists.
Deploys ship on Tuesday. A Friday deploy is a human decision, not an agent decision.
<!-- dox:keep end -->تعليقات Markdown لا تظهر في الصفحة، والوكيل لا يزال يقرؤها. الآن اجعل بقاء الكتلة قابلاً للتحقق، بحيث يفشل أي تمرير يمحوها بشكل صاخب. شغّل هذا في CI (التكامل المستمر) مع كل طلب سحب (pull request):
git fetch -q origin main
sed -n '/dox:keep start/,/dox:keep end/p' AGENTS.md > /tmp/keep.head
git show origin/main:AGENTS.md | sed -n '/dox:keep start/,/dox:keep end/p' > /tmp/keep.base
diff -u /tmp/keep.base /tmp/keep.headلا يطبع diff أي شيء ويخرج بالقيمة 0 عندما تظل الكتلة دون تغيير. أي مخرجات تعني أن التمرير أعاد كتابة نص مملوك للبشر، لذا يجب على شخص ما الموافقة عليه أو التراجع عنه. يستمر الفحص دون الحاجة إلى أن يتذكره أحد.
أعد التوليد عند طلب السحب (pull request)، لا وفق مؤقت زمني
أفضل لحظة لتحديث وثيقة هي لحظة إجراء التعديل الذي جعلها غير دقيقة. أدرج عملية DOX في نفس طلب السحب الذي يتضمن التغيير الهيكلي، ليبقى حجم الـdiff صغيراً بما يكفي لقراءته فعلياً.
إليك فحص حظر يفرض ذلك:
#!/usr/bin/env bash
set -euo pipefail
git fetch -q origin main
base=$(git merge-base origin/main HEAD)
changed=$(git diff --name-only "$base" HEAD)
if grep -qE '^(src|apps|packages)/' <<<"$changed" && ! grep -q 'AGENTS\.md$' <<<"$changed"; then
echo "Code changed but no AGENTS.md was touched. Run a DOX pass, or say why not."
exit 1
fiعدّل المسارات لتناسب مستودعك. تكمن القيمة في أن الفحص يفشل على الفرع (branch)، حيث يكون الإصلاح غير مكلف، ويفشل لسبب يمكن للمراجع اتخاذ إجراء بشأنه.
الجدولة هي وسيلة احتياطية وليست الآلية الأساسية. المهمة الأسبوعية تلتقط ما لم يلاحظه أحد على الفرع: ملفات نُقلت بسبب rebase، حزمة حُذفت في عملية دمج (merge)، أو وثيقة تشير إلى دليل لم يعد موجوداً. شغّل المهمة على خادم صغير، وهو نفس الخادم الذي قد تستخدمه لـ تشغيل وكيل برمجي على VPS، واجعلها تفتح طلب سحب بدلاً من الدفع (push) مباشرة إلى الفرع الرئيسي.
#!/usr/bin/env bash
set -euo pipefail
cd /srv/src/myapp
git fetch -q origin
git switch -c "dox/refresh-$(date +%Y%m%d)" origin/main
# Your agent CLI goes on the next line, in whatever non-interactive mode it offers.
# Prompt: "Run a DOX pass over this repository. Change AGENTS.md files only."
git add '*AGENTS.md'
git commit -m "dox: refresh AGENTS.md tree" || { echo "nothing to refresh"; exit 0; }
git push -q -u origin HEAD
gh pr create --fillهذا التعليق هو عنصر نائب عن قصد. لكل وكيل واجهة سطر أوامر (CLI) خاصة به وعلامة (flag) خاصة للتشغيل غير التفاعلي، والأمر الذي تنسخه من صفحة ويب ولا يطابق إصدارك سيفشل داخل cron حيث لا يرى أحد الخطأ. املأ البيانات وشغّل البرنامج النصي يدوياً مرة واحدة قبل جدولته. الـ || exit 0 مهم أيضاً: git commit يخرج بقيمة غير صفرية مع nothing to commit, working tree clean عندما تكون الشجرة محدثة بالفعل، وتحت set -e سيؤدي ذلك إلى الإبلاغ عن تشغيل سليم على أنه فشل.
كل عملية تستهلك tokens، لأن "القراءة قبل التعديل" تجعل الوكيل يقرأ السلسلة بأكملها في كل مهمة. هذه هي المقايضة، ومن الجدير مراقبتها إذا كنت بالفعل تحسب تكلفة ما يشغله وكيلك.
المستودعات الموحدة (Monorepos): عقود متعددة، فهرس واحد
إن وجود ملف AGENTS.md واحد في جذر مستودع يحتوي على أربعين حزمة يؤدي إلى إنشاء فرق (diff) في إعادة التوليد لا يقرؤه أحد، ووثيقة تكون في الغالب غير ذات صلة بما يفعله الوكيل في الوقت الحالي. الحل في dox هو فهرس وثائق الأطفال (Child DOX Index): يحتفظ الجذر بقواعد المستودع ككل ويشير إلى أطفاله، بينما تمتلك كل حدود متينة ملفها الخاص. كيفية ترتيب هذه الشجرة، والأدوات التي تقرأ الملفات المتداخلة، مشروحة في ملفات AGENTS.md المتداخلة للمستودعات الموحدة.
ما يغيره dox هو نطاق المراجعة. يجب أن يؤدي طلب السحب (pull request) الذي يمس packages/api إلى إنتاج فرق في الوثائق داخل packages/api وليس في أي مكان آخر:
git diff --stat -- '*AGENTS.md'إذا كان هذا الأمر يسرد ستة ملفات لتغيير في حزمة واحدة، فإن الشجرة خاطئة. إما أن الحدود واسعة جداً، أو أن قاعدة تنتمي إلى الجذر قد نُسخت في كل طفل. يوضح dox الحل مباشرة: القواعد العامة توضع في وثائق الأب، والتفاصيل الملموسة توضع في وثائق الطفل. القواعد المكررة هي ما يجعل التمرير الروتيني يعيد كتابة كل شيء. إذا كانت نفس القواعد تنطبق فعلياً عبر مستودعات منفصلة، فهذه مشكلة مختلفة، وتعد مشاركة مهارات الوكيل عبر المستودعات الأداة الأفضل لذلك.
مراجعة فرق الملفات (diff) كأنها شيفرة برمجية
من السهل الموافقة على فرق ملفات التوثيق المُنشأ آلياً دون قراءته، وهذا هو السبب في شحن ملف خاطئ. اقرأ الفرق بالشك الذي تعامل به الشيفرة البرمجية المُنشأة، وابحث عن أربعة أمور:
- أي أمر يذكره الملف الآن، والذي يجب عليك تشغيله بنفسك قبل الدمج. تعليمات البناء المخترعة هي أكثر أسباب الفشل شيوعاً.
- أي سطر محذوف كان يحمل غاية معينة. الإضافات رخيصة، أما الحذف فهو حيث تقع الخسارة.
- أي مسار مطلق، أو اسم مضيف، أو رابط URL داخلي، أو أي شيء يشبه بيانات الاعتماد.
- أي إدخال في الجرد لشيء لم يعد موجوداً، وهو ما يقوم
lsبتسويته في ثانية.
ثم تحقق من الحجم باستخدام wc -l AGENTS.md. إذا تجاوز ملف root مائتي سطر، فهذه إشارة لتقسيمه، لأن القيمة الكاملة للسلسلة تكمن في أن الوكيل يقرأ الجزء الصغير ذي الصلة بدلاً من قراءة كل شيء.
عند حدوث عطل
حذف التمرير كتلة الأوامر الخاصة بك. يطبع الفحص diff أعلاه الأسطر المحذوفة. استعد الملف من نقطة الفرع باستخدام git restore --source=origin/main AGENTS.md، ثم أعد تشغيل التمرير بتعليمات أكثر دقة تحدد الأقسام التي يمكنها تعديلها.
تمت إعادة إنشاء فرعين معاً. ستحصل على CONFLICT (content): Merge conflict in AGENTS.md وعلامات تعارض <<<<<<< HEAD داخل الملف. لا تقم بتحرير العلامات يدوياً. بما أن الملف مُنشأ آلياً، فإن الحل الصحيح هو إجراء تمرير جديد على الشجرة المدمجة.
يتجاهل الوكيل الملف تماماً. تحقق من اسم الملف الذي تقرؤه أداتك فعلياً. إذا كانت تقرأ ملفاً مختلفاً، وجّهها إلى نفس المحتوى باستخدام ln -s AGENTS.md CLAUDE.md وقم بعمل commit للرابط الرمزي (symlink)، لكي تحتفظ بمصدر واحد بدلاً من وثيقتين تتباعدان عن بعضهما.
نمت الشجرة بفروع لم يفهرسها أحد. قارن مخرجات find . -name AGENTS.md بمدخلات الفهرس في الوثائق الأصلية. الفرع الذي لا يذكره أي فهرس هو فرع سيتجاوزه الوكيل مباشرة.
متى يكون استخدام المولد (Generator) مبالغاً فيه
عندما يكون لديك حزمة واحدة، وأمر اختبار واحد، وشخصان يعرفان المستودع جيداً، اكتب العشرين سطراً يدوياً. ملف AGENTS.md المكون من عشرين سطراً لا يتقادم بالسرعة التي تبرر بناء شجرة، وفهرس، وفحص CI، ومهمة دورية أسبوعية. أعد قراءته عند تغيير عملية البناء. هذه هي تكلفة الصيانة الكاملة، وهي أقل من تكلفة الآليات المحيطة بها.
تستحق أدوات التوثيق (dox) العناء عندما يحتوي المستودع على حدود لا يستوعبها شخص واحد في ذهنه: عدة حزم بقواعد مختلفة، أو مساهمون ينضمون دون خلفية مسبقة. القيمة ليست في النص المولد، بل في أن التوثيق يصبح شيئاً يمكن لطلب السحب (pull request) أن يفشل بسببه، وهو السبب الوحيد الذي يجعل أي ملف في المستودع محدثاً.
FAQ
هل أحتاج إلى تثبيت أي شيء لاستخدام dox؟
لا. dox عبارة عن ملف Markdown واحد، مرخص بموجب رخصة MIT، واعتباراً من 11 أغسطس 2026 لا يشحن المستودع أي حزمة ولا يصدر أي إصدارات. انسخ محتوياته إلى ملف AGENTS.md في مشروعك، وسوف يتبع وكيل البرمجة الخاص بك القواعد الواردة فيه. ثبّت الـ commit الذي نسخته، وهو f34ec7ad1055d3393887e5a2670e8cb7320c9165 وقت كتابة هذا النص، واذكره في رسالة الـ commit الخاصة بك حتى تتمكن لاحقاً من معرفة الإصدار الذي بُنيت شجرة مشروعك بناءً عليه.
كيف أمنع عملية إعادة التوليد من حذف قواعدي المكتوبة يدوياً؟
افصل بين النية والمخزون. ضع التفكير المستدام في مستند منفصل، وأي شيء يجب أن يبقى داخل AGENTS.md ضعه داخل كتلة محددة. ثم تحقق من هذه الكتلة في نظام CI: استخرجها من الفرع ومن origin/main باستخدام sed، وقارن بينهما باستخدام diff، واجعل عملية البناء تفشل عند وجود أي اختلاف. يقوم شخص ما بعد ذلك بالموافقة على التغيير أو التراجع عنه، بدلاً من تمريره دون ملاحظة داخل diff كبير.
كم مرة يجب أن أعيد توليد AGENTS.md؟
في طلب السحب (pull request) الذي يجعلها غير صحيحة. التغيير الهيكلي وتوثيقه ينتميان إلى diff واحد، لأن تلك هي اللحظة الوحيدة التي يمتلك فيها شخص ما السياق لمراجعة كليهما. التمرير المجدول أسبوعياً هو النسخة الاحتياطية للانحراف الذي قد يتسرب خارج الفرع، ويجب أن يفتح طلب سحب بدلاً من الالتزام (commit) مباشرة في الفرع الرئيسي main.
هل يجب أن توضع أوامر البناء في ملف AGENTS.md الجذري أم في ملف فرعي؟
في أقرب مستند يمتلكها. القواعد الخاصة بالمستودع بالكامل وفهرس الأبناء توضع في الجذر. الأمر الذي ينطبق على حزمة واحدة يوضع في ملف AGENTS.md الخاص بتلك الحزمة. يحل dox التعارضات بناءً على المسافة: المستند الأقرب يتحكم في التفاصيل المحلية، ولا يجوز لأي مستند فرعي إضعاف قاعدة من المستند الأب. نسخ الأمر نفسه في كل مستند فرعي هو ما يجعل عملية التمرير الروتينية تعيد كتابة الشجرة بأكملها.
هل يستحق dox العناء بالنسبة لمستودع صغير؟
غالباً لا. حزمة واحدة مع أمر اختبار واحد وملف AGENTS.md مكون من عشرين سطراً تتدهور ببطء، ويمكنك إصلاحها في الدقيقة التي تلاحظ فيها المشكلة. تظهر قيمة dox عندما يحتوي المستودع على عدة حدود بقواعد مختلفة، أو مساهمين يفتقرون إلى الخلفية المعرفية، لأن سلسلة المستندات تقوم حينها بعمل لا يقوم به أي شخص بمفرده.