الوثائق · 03

الوكلاء والتفويضات الدائمة.

يملك الوكلاء في CommandAGI تحكماً فورياً في آلات حقيقية. تأتي الصلاحية من مكان واحد — تفويض دائم أنشأه شخص — ويُسجَّل كل إجراء قبل أن يحدث.

بلا إنسان في الحلقة — بالتصميم

صُمم CommandAGI للآلات التي تعمل دون مراقبة. يؤهّل الوكيل الذي يملك تفويضاً وحدةً، ويشغّل البرامج ويرسل الأوامر في الوقت الفعلي، عبر منضدة العمل أو API أو MCP، دون تأكيد لكل إجراء. ما يحفظ الأمان ليس شخصاً يراقب، بل التفويض وحدود المشغّل والسجل.

الجهات الفاعلة

كل ما يتصرف هو جهة فاعلة: agent:<name> أو person:<name>. تُثبت الجهة الفاعلة هويتها ببيانات اعتماد، ولا تكفي تسمية نفسها. يُرفض الطلب الذي يقول فقط من هو.

  • بيانات اعتماد المضيف — cagp_…، تُصدرها مرة واحدة commandagi grant token --principal agent:<name> (أو عند إضافة تفويض). يخزّن المضيف بصمة SHA-256 لها فقط. يدوّرها grant token، ويزيلها grant forget.
  • بيانات اعتماد الحساب — cagc.<payload>.<signature>، موقّعة بمفتاح حسابك (Ed25519) للوكلاء الذين يعملون في السحابة. تسمّي الجهة الفاعلة والحساب وتاريخ انتهاء، واختيارياً مضيفاً واحداً، ولا تُقبل إلا للتفويضات التي أصدرها ذلك الحساب. ألغها بـ grant revoke-credential.

التفويضات الدائمة

التفويض الدائم صلاحية يمنحها حساب لجهة فاعلة واحدة، بفعل صريح من شخص. لا يُنشئ أي مسار أداة أو وكيل تفويضاً ولا يوسّعه؛ ومفتاح API الخاص بالوكيل يُرفض في كل مسار يغيّر الصلاحيات.

shell
commandagi grant add --principal agent:night-shift \
  --world shop --unit mill-1 --channel gcode \
  --verb open --verb arm --verb run --verb send \
  --for 8h --note "night shift"
commandagi grant list
commandagi grant revoke g-3f9a1c20b7de

يحدد التفويض عالماً، واختيارياً وحدات وقنوات وأفعالاً — وإن حذفت أحدها فهو يشمل الكل. وقد ينتهي (--for 8h، أو --expires <ISO time>). تُحفظ التفويضات في ~/.commandagi/grants.json، وتُقرأ عند كل إجراء، ويمكن إنشاؤها أيضاً في منضدة العمل تحت الإعدادات ← تفويضات. ملف التفويضات المشوّه لا يمنح أي تفويض على الإطلاق.

json
{ "grants": [ { "id": "g-3f9a1c20b7de", "principal": "agent:night-shift",
  "grantedBy": "acct:user:u_8f2k", "world": "shop", "units": ["mill-1"],
  "channels": ["gcode"], "verbs": ["open", "arm", "run", "send"],
  "expires": "2026-10-01T06:00:00Z", "note": "night shift" } ] }

ينشئ الأمر نفسه ثلاثة أنواع أخرى من التفويض: --file PREFIX… (كتابة ملفات تحت مسار)، و--outreach APP… --per-day N (إرسال رسائل عبر التطبيقات المتصلة)، و--market VENUE… --symbol S --max-qty N --max-notional N --per-day N (وضع الأوامر).

التفويضات تنطبق على العوالم الفيزيائية. عالم المحاكاة لا يحتاج إلى أي تفويض.

الأفعال والتأهيل والإيقاف الآمن

يمنح التفويض أربعة أفعال: فتح قناة، تأهيل وحدة، تنفيذ برنامج، إرسال أمر.

  • تفتح المشغّلات التي تحرّك العتاد غير مؤهَّلة. يستطيع أي جهة فاعلة لها تفويض على الوحدة تأهيلها. والجلسة المؤهَّلة التي تبقى خاملة خمس دقائق تُلغي تأهيلها بنفسها.
  • المشغّلات التي تأخذ الإدخال فقط — صدفة، أو نواة Python، أو تسليم مهمة — لا تحتاج إلى تأهيل؛ يُفحص التفويض عند كل إدخال.
  • الإيقاف الآمن مسموح دائماً. stop وdisarm وclose، وأوامر الإيقاف الآمن مثل تعليق التغذية والإيقاف المؤقت وإيقاف الطوارئ وإيقاف العزم، مسموحة لأي جهة تحمل أي تفويض ساري على الوحدة، ولمن فتح الجلسة، ولشخص الحساب نفسه. وإلغاء أمر قائم هو أيضاً إيقاف آمن.

القواعد التي يتبعها كل إجراء

  • يُسجَّل قبل الإرسال. قبل استدعاء المشغّل، تُلحق ملاحظة — الجهة الفاعلة والإجراء — بتدفق التشغيل وتُفرَّغ إلى القرص. يرفض المجلد المقروء فقط الإجراء بدلاً من التصرف دون سجل.
  • الإقرار ليس حالة. الردّ أو ok لا يعني أبداً أن الحالة المطلوبة تحققت. تبقى الأوامر معلّقة حتى تُبلغ الآلة عن حالة.
  • يبقى المجهول مجهولاً. يُسجَّل انقطاع الوصلة كـ state: unknown. التدفق الذي ينتهي دون سجل نهاية يُقرأ مقاطَع: الحالة مجهولة.
  • لا إعادة محاولة صامتة. لا يعيد النظام أبداً إرسال أمر مادي. قد يقرر الوكيل المحاولة مرة أخرى، ويُسجَّل ذلك القرار كأمر مستقل.
  • الحدود من عمل المشغّل. تُطبَّق الحدود المعلنة والفواصل الزمنية والأفعال المسموحة من المشغّل، لا من شخص. تُضبط مدخلات التدفق: إجراء واحد في كل مرة، وبفاصل 30 ms على الأقل.
  • المحاكاة والفيزياء لا تختلطان. يتبع التشغيل عالماً واحداً، ويجب أن يطابق مصدر سجلاته نوع ذلك العالم.

المحادثات ووكيلها

بدء محادثة في عالم فيزيائي يمنح وكيل المحادثة (threads.agent، وagent:mcp افتراضياً) كل الأفعال على وحدات ذلك العالم، لمدة 24 ساعة كحد أقصى، ويُلغى هذا التفويض عند إغلاق المحادثة. أوقف ذلك بالإعداد "threads.agentControl": false.

التالي

اربط وكيلاً بهذا كله عبر MCP: SDK وMCP.