工单与委派
工单是 Control Center 跟踪工作所用的单位。它刻意做得很_简单_:一个标题、一段正文、一个状态、一位负责人,以及它在树中的位置。它不是智能体执行的对象——智能体的工作存在于对话中,而一次运行的结构化输出记录在运行日志上。
分配只记录归属,不派发任何东西
标题为“分配只记录归属,不派发任何东西”的部分这是关于工单最需要弄清楚的一点。
设置 assignedAgentId 会写入一个字段,并发布一个 TicketAssigned
领域事件。该事件既是审计与通知信号,也是流水线触发器。把工单分配给智能体不会启动任何运行。 不存在监视 assignedAgentId 并唤醒对应智能体的工单派发器。
例外是团队:当设置了 assignedTeamId 时,TeamRoutingService 会带着操作协议和成员名单派发团队负责人。
如果你想让某个特定的智能体处理某张工单,你要在对话里请它去做,或者由某个流水线步骤派发它,再或者由另一个智能体把工作委派给它。把工单分配给某个智能体然后坐等,是唯一永远不会产生任何工作的事情。
镜像与覆盖层
标题为“镜像与覆盖层”的部分一张工单可以完全存在于本地,也可以由外部跟踪器支撑,而同一行记录会同时承载这两部分。
镜像——提供方、外部键、URL、标题、描述、优先级、标签、原始状态与规范化状态、时间戳——在工单来自远程时充当缓存。此时远程才是事实来源,一次刷新会整体重写镜像。
覆盖层——分配、委派、空间关联、父工单、项目、关联的 PR——只属于 Control Center。跟踪器对它一无所知,刷新也绝不会触碰它。
正是这种划分才让同步本身变得安全:厂商拉取可以对镜像造成破坏性影响,却绝不会丢失叠加其上的编排元数据。
生命周期图约束的是智能体,而不是你
标题为“生命周期图约束的是智能体,而不是你”的部分状态按 backlog → open → inProgress → inReview → done 流转,其中 blocked 是一条旁路,failed / cancelled 是另外两个终态。
转换图只在智能体与自动化路径上强制执行——也就是 MCP 工具和对账器。那里的非法转换会被记录并忽略,因此迷糊的智能体无法把工单从终态倒着走回去。
UI 中每一次由用户驱动的变更都会传入 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。
不要把委派深度上限(在 delegate_task 链上为 3)与内置执行框架的子智能体嵌套上限(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 列;流水线的耦合关系存在于智能体运行日志上。