رفتن به محتوا

تیکت‌ها و واگذاری

تیکت واحد کاری است که Control Center ردیابی می‌کند. به‌عمد یک مصنوع کمهوش است: یک عنوان، یک متن، یک وضعیت، یک مالک و جایی در یک درخت. آن چیزی نیست که عامل‌ها در برابر آن کار را اجرا می‌کنند — کار عامل در گفتگوها زندگی می‌کند و خروجی ساختاریافتهٔ یک اجرا روی گزارش اجرا می‌نشیند.

تخصیص مالکیت را ثبت می‌کند؛ چیزی را اعزام نمی‌کند

بخش با عنوان “تخصیص مالکیت را ثبت می‌کند؛ چیزی را اعزام نمی‌کند”

این مهم‌ترین نکته‌ای است که دربارهٔ تیکت‌ها باید درست بفهمید.

تنظیم assignedAgentId یک فیلد می‌نویسد و یک رویداد دامنه با نام TicketAssigned منتشر می‌کند. آن رویداد یک سیگنال حسابرسی و اعلان و همچنین یک تریگر پایپ‌لاین است. تخصیص به یک عامل هیچ اجرایی را شروع نمی‌کند. هیچ اعزام‌کنندهٔ تیکتی وجود ندارد که assignedAgentId را بپاید و آن عامل را بیدار کند.

استثنا یک تیم است: وقتی assignedTeamId تنظیم شده باشد، TeamRoutingService سرگروه تیم را همراه با پروتکل عملیاتی و فهرست اعضا اعزام می‌کند.

اگر می‌خواهید عامل مشخصی روی یک تیکت کار کند، در یک گفتگو از آن می‌خواهید، یا یک گام پایپ‌لاین آن را اعزام می‌کند، یا عامل دیگری به آن واگذار می‌کند. تخصیص دادن یک تیکت به یک عامل و منتظر ماندن، تنها کاری است که هرگز کاری تولید نمی‌کند.

یک تیکت می‌تواند کاملاً محلی باشد یا پشتوانهٔ آن یک ردیاب بیرونی باشد، و هر دو حالت را روی یک ردیف نگه می‌دارد.

آینه — ارائه‌دهنده، کلید خارجی، URL، عنوان، شرح، اولویت، برچسب‌ها، وضعیت خام و نرمال‌شده، برچسب‌های زمانی — وقتی تیکت راه دور است یک کش است. آنجا منبع حقیقت، راه دور است و یک تازه‌سازی، آینه را یکسره بازنویسی می‌کند.

لایهٔ رویی — تخصیص، واگذاری، پیوند فضا، والد، پروژه، PRهای پیوندشده — فقط در 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 را اجرا می‌کند: جهشی که از سقف عمق ۳ فراتر رود، جهشی بازگشتی به عاملی که پیش‌تر در زنجیره است (تشخیص چرخه)، یک سقف خودمختاری (سطح مؤثر عامل واگذارشده در فضا نباید از سطح واگذارکننده بیشتر باشد) و یک پاکت بودجه (واگذاری از بودجهٔ توقف سختِ باقی‌ماندهٔ واگذارکننده برداشت می‌کند و نمی‌تواند بیشتر خلق کند). سیم‌کشی تولیدی هر دو پورت حل‌کننده را تأمین می‌کند. خودمختاری و بودجه وقتی from_agent_id حذف شده باشد رد می‌شوند (بودجهٔ نامحدود / بدون‌سیاست هم می‌گذرد). یک رد به‌صورت DelegationRefusedException پرتاب می‌شود که پیامش عیناً به عامل واگذارکننده می‌رسد — یک انکار پرصدا، هرگز یک بی‌عملی بی‌صدا.

delegate_ticket همتای قدیمی‌تر و بی‌محافظ است: مستقیم createTicket را صدا می‌زند و همهٔ گاردها را رد می‌کند. delegate_task را ترجیح دهید.

سقف عمق واگذاری (۳، در زنجیره‌های delegate_task) را با سقف تودرتویی زیرعامل در هارنس داخلی (۲) اشتباه نگیرید. این‌ها محدودیت‌های متفاوتی روی سازوکارهای متفاوت‌اند.

سلسله‌مراتب، پیوندها و پروژه‌ها

بخش با عنوان “سلسله‌مراتب، پیوندها و پروژه‌ها”

رابطه‌های والد و زیرایشو روی 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 روی تیکت وجود ندارد؛ جفت‌شدگی پایپ‌لاین روی گزارش اجرای عامل زندگی می‌کند.