التذاكر والتفويض
التذكرة وحدة العمل التي يتتبعها Control Center. وهي عمدًا كيان بسيط: عنوان، ومتن، وحالة، ومالك، وموضع في شجرة. ليست ما يُنفَّذ الوكلاء عليه، فعمل الوكيل يعيش في المحادثات، والمخرج المنظَّم للتشغيل يعيش في سجل التشغيل.
الإسناد يسجّل الملكية، ولا يُرسل شيئًا
قسم بعنوان “الإسناد يسجّل الملكية، ولا يُرسل شيئًا”هذا أهم ما يُفهَم عن التذاكر على وجهه.
ضبط assignedAgentId يكتب حقلًا وينشر حدث نطاق باسم TicketAssigned. هذا الحدث إشارة للتدقيق وللإشعار، ومشغّل لخط أنابيب. الإسناد إلى وكيل لا يبدأ تشغيلًا. لا موزّع تذاكر يراقب assignedAgentId ويوقظ ذلك الوكيل.
الاستثناء هو الفريق: عند ضبط assignedTeamId يُرسل TeamRoutingService تشغيل قائد الفريق، ومعه بروتوكول التشغيل والكشف.
إن أردت أن يعمل وكيل بعينه على تذكرة، فاطلب منه ذلك في محادثة، أو أرسله بخطوة في خط أنابيب، أو فوّض العمل إليه من وكيل آخر. إسناد التذكرة إلى وكيل ثم الانتظار هو التصرف الوحيد الذي لن ينتج عملًا.
المرآة والتراكب
قسم بعنوان “المرآة والتراكب”قد تكون التذكرة محلية خالصة أو مدعومة بمتتبع خارجي، والصف الواحد يحمل الجهتين معًا.
المرآة، وهي المزوّد والمفتاح الخارجي وURL والعنوان والوصف والأولوية والتسميات والحالة الخام والحالة المطبَّعة والطوابع الزمنية، ذاكرة مؤقتة حين تكون التذكرة بعيدة. البعيد هناك مصدر الحقيقة، وإعادة الجلب تعيد كتابة المرآة كلها.
التراكب، وهو الإسناد والتفويض وربط المساحة والأصل والمشروع وطلبات السحب المرتبطة، خاص بـ Control Center. المتتبع لا يعرف عنه شيئًا، وإعادة الجلب لا تمسّه.
هذا الفصل هو ما يجعل المزامنة آمنة من أساسها: سحب من المورّد قد يهدم المرآة، وبيانات التنسيق الوصفية التي فوقها تبقى.
مخطط دورة الحياة يقيّد الوكلاء، لا أنت
قسم بعنوان “مخطط دورة الحياة يقيّد الوكلاء، لا أنت”تسير الحالات على backlog → open → inProgress → inReview → done، وblocked حلقة جانبية، وfailed / cancelled الحالتان النهائيتان الأخريان.
يُفرَض مخطط الانتقال على مسار الوكيل والأتمتة فقط، أي أدوات MCP وخدمات المصالحة. الانتقال غير الجائز هناك يُسجَّل ويُتجاهل، فلا يستطيع وكيل مرتبك أن يُخرج تذكرة من حالة نهائية إلى الوراء.
كل تغيير يجريه المستخدم في الواجهة يمر بقيمة force: true ويتجاوز المخطط كله. يجوز للإنسان أن ينقل التذكرة إلى أي حالة تعرضها قائمة الاختيار، ومنها إعادة فتح حالة نهائية. قائمة الاختيار لا تعرض failed، والوكلاء يضبطونها عبر fail_ticket. المخطط حاجز حماية للأتمتة، لا قاعدة تحكم مسار العمل.
TicketWorkflowService يملك كل تعديل عبر نقطة اختناق واحدة: تحمّل الصف، وتتحقق أنه يخص مساحة عمل المستدعي، وتكتب بقيمة version متوقعة، فلا يطمس تعديلان متزامنان أحدهما الآخر في صمت.
لجدول الحالات الكامل، والانتقالات، وقائمة الحقول، وأنواع العلاقات، انظر دورة حياة التذكرة.
المنشأ: كيف وُجدت التذكرة
قسم بعنوان “المنشأ: كيف وُجدت التذكرة”لكل تذكرة originKind. في التعداد خمس قيم، manual وpipelineStep وagentDelegation وexternalSync وrecovery، لكن اثنتين فقط تُكتبان اليوم: manual (الافتراضي عند createTicket، ويشمل ذلك الأبناء المفوَّضين) وexternalSync (محرّك المزامنة، عند السحب من المورّد). TicketWorkflowService.createTicket لا يأخذ وسيط منشأ، فلا تُكتَب pipelineStep ولا agentDelegation ولا recovery في أي صف.
التفويض المحروس
قسم بعنوان “التفويض المحروس”التفويض هو حيث ينشئ وكيل عملًا لوكيل آخر، وهو الموضع الذي قد يتسرب منه امتياز، فالحراسة على الخادم في نقطة اختناق، لا في تعليمات المطالبة.
يمر delegate_task عبر TicketWorkflowService.delegateGuarded، فيحسب عمق الابن وجذره من سلسلة الأصل، ثم يجري فحوص DelegationGuards الأربعة: قفزة تتجاوز سقف عمق قدره 3، وقفزة ترجع إلى وكيل موجود أصلًا في السلسلة (كشف الدورات)، وسقف الاستقلالية (لا يتجاوز المستوى الفعلي للمفوَّض إليه في المساحة مستوى المفوِّض)، وغلاف الميزانية (يُخصم التفويض من ميزانية الحد الصارم المتبقية لدى المفوِّض، ولا يستحدث ميزانية فوقها). وتوصيلات الإنتاج توفّر منفذي الحل كليهما. تُتخطى الاستقلالية والميزانية حين لا يُمرَّر from_agent_id (والميزانية غير المحدودة، أو التي بلا سياسة، تمر أيضًا). الرفض استثناء DelegationRefusedException تصل رسالته إلى الوكيل المفوِّض بنصها: رفض يُسمَع، لا عملية صامتة.
delegate_ticket الشقيق الأقدم، وهو غير محروس: يستدعي createTicket مباشرة ويتجاوز الحراسة كلها. فضّل delegate_task.
لا تخلط بين سقف عمق التفويض (3، على سلاسل delegate_task) وسقف تداخل الوكلاء الفرعيين في الإطار المضمّن (2). هما حدّان مختلفان على آليتين مختلفتين.
التسلسل والروابط والمشاريع
قسم بعنوان “التسلسل والروابط والمشاريع”علاقات الأصل والتذاكر الفرعية تعيش في tickets.parent_ticket_id، وتملكها setParent / clearParent. وليست صفوف ticket_links، فمن يقرأ علاقات تذكرة يجمع المصدرين.
ticket_links يحمل الروابط الموجَّهة بين تذاكر لا علاقة هرمية بينها:
| نوع الرابط | المعنى |
|---|---|
blocks |
المصدر يعوق الهدف |
relatesTo |
التذكرتان مرتبطتان (علاقة متناظرة) |
duplicateOf |
المصدر نسخة مكررة من الهدف |
المشروع تجميع لتذاكر على نطاق مساحة العمل نحو هدف مشترك. المشاريع خاصة بـ Control Center، ولا تُزامَن إلى مزوّد خارجي.
المتعاونون
قسم بعنوان “المتعاونون”صفوف TicketCollaborator هي كيف يُربَط أكثر من طرف واحد بتذكرة، بدور assignee أو collaborator أو reviewer. البشر والوكلاء صفوف متكافئة، principalId إلى جانب collaboratorType، بلا قيمة خاصة تمثّل «المستخدم»، وبلا مفتاح أجنبي إلى جدول المستخدمين ولا إلى جدول الوكلاء.
المزامنة الخارجية
قسم بعنوان “المزامنة الخارجية”تذكرة Control Center هي السجل الأساس. حذف التذكرة محلي فقط، فالتذكرة التي يسندها مورّد لا تُحذف من المتتبع إن حذفتها، وقد تعود في المزامنة التالية. ويتتابع الحذف إلى المتعاونين والتذاكر الفرعية.
تُحَل بيانات اعتماد المحوّل من مخازن بيانات الاعتماد على الخادم (مفتاح Linear أو رمز GitHub، إن لصقته في الإعدادات، يُلتقط في الطلب التالي، ولا تفعل البيئة غير بذر تلك المخازن).
التذاكر وخطوط الأنابيب
قسم بعنوان “التذاكر وخطوط الأنابيب”لا عقدة في خط الأنابيب تنشئ تذكرة أو تكملها أو تلغيها. لا خطوة من هذا النوع في اللوحة، والمحرّك لا يستدعي TicketWorkflowService. ويبقى لمشغّل خط الأنابيب أن ينطلق عند TicketAssigned أو TicketCompleted أو TicketFailed أو TicketCancelled (وهذه الأربعة هي أحداث التذكرة التي يقابلها EventPayloadMapper فعلًا). لا عمود pipelineRunId على التذكرة، وارتباطها بخط الأنابيب يعيش في سجل تشغيل الوكيل.
انظر أيضًا
قسم بعنوان “انظر أيضًا”- خطوط الأنابيب والأتمتة: أحداث التذكرة قد تشغّل خط أنابيب
- التنسيق: من أين يأتي مخطط DAG للتذاكر الفرعية
- نموذج الوكيل: لمن تُسنَد التذكرة
- أحداث النطاق: أحداث دورة حياة التذكرة
- دورة حياة التذكرة: الحالات والحقول والانتقالات والعلاقات
- إنشاء التذاكر وإدارتها
- تفويض العمل إلى الوكلاء
- تنظيم العمل بالمشاريع