延续系列,详解Agent任务从认领到完成全生命周期中文件状态机与工程Rail的协作方式,给出生命周期状态与各类信号的对应表。
任务体显示 status: done,但任务文件仍停留在 active 目录中。一份开发报告存在,但所需兼容性证据却缺失。UI 看到了报告并发布了下游部署任务。哪个信号是权威的?
可靠的回答不是选择看起来最完整的那一个字段。这些信号回答的是不同的问题:路径标识当前的生命周期状态;事件记录任务如何流转;报告说明执行者返回了什么;接受决定说明是否有授权角色认可了它。
本文追踪一个任务经历其完整生命周期,展示文件系统状态机与工程轨道如何协作。交付成果是一组不变量,可以转化为测试用例,而不仅仅是目录命名的指南。
不要把四个事实压缩成一个 done
这些事实可以相互引用,但不能互相替代。报告不等于批准。body 字段不等于当前路径。_lifecycle/review/ 中的一个 TASK 不能证明存在一个独立的 REVIEW-* 治理信封。
当前的 FCoP v3 规范明确区分了 review 的两种含义。目录是 TASK 的生命周期阶段。reviews/ 下的文件是对一个产物的独立判断。两者可以共存,但协议并未建立自动的一对一关系。
任务经历五个阶段
以"添加 CSV 导出并运行兼容性测试"的请求作为运行示例。
PM 从一个已批准的需求创建一个新任务。FCoP TASK 文件名包含类型、日期、序号、发送者和接收者,文件进入 _lifecycle/inbox/。
创建意味着工作对象现在已存在。它不意味着已有 agent 认领了它或执行已开始。团队运行时还需要 root-task、parent-task 和 thread identity,以便后续子任务和报告能回到同一个责任树。
当授权的生命周期工具认领任务时,TASK 从 inbox 移动到 active。协议要求一个转换事件,包含 from、to、by 和 tool。
FCoP 的 write-then-rename 模式不是将"编辑 body"、"移动旧文件"和"追加日志"作为三个松散耦合的动作。它在一临时文件中准备目标内容——包括新事件——先持久化,再在同一个文件系统边界内执行重命名。重命名就是可观察的提交点。
POSIX.1-2024 为 rename() 指定了原子目录条目行为:观察者应看到旧条目或新条目,而不是中间的目录名。这种保证有局限性。它不是跨挂载点的事务,它本身不能证明所有目录元数据的崩溃持久性,它也不能使一个松弛的网络文件系统变成强一致的。
还有另一个边界。如果一个实现发布了一个新的目标文件,然后才删除源文件,rename 使目标发布原子化;但它不会将"目标发布"和"源删除"变成一个跨目录事务。这两个表述并不矛盾:本地文件系统的 rename() 使一次目录条目替换原子化,而双阶段冲突只有在上层协议将"发布目标"和"删除源"作为两个可中断操作组合时才会产生。在崩溃窗口期间,一个 TASK 可能同时留在 inbox/ 和 active/ 中。"路径解决 NOW;事件记录 PAST"不是本文的修辞总结:FCoP v3 §§0.1、1.4 和 2.3 明确将路径确定的当前状态与仅追加的转换历史分开,并禁止通过重放事件来推导当前状态。因此读者不能选择事件时间戳明显更新的那个目录。正确行为是报告并保留双阶段冲突,并停止将其投射为单一当前状态;清理或恢复必须使用后续的授权生命周期动作。
因此精确的论断是:rename 可以在声明的文件系统边界内提供一个原子的目标发布点;它不会使整个多 agent 系统天生具备并发安全性。
一个容易忽略的缺口:完整发布不等于排他认领
这不是文字游戏,但它不是当前本地优先部署的正常拓扑。经测试的 CodeFlowMu V1.9.7 形态是:一个 Runtime 服务对应一个本地项目根。其 controlled-restart 记录显示当前进程持有写锁并保留一致的根绑定。检查的材料未声明支持两个独立的 CodeFlowMu Runtime 共享一个项目文件夹,也没有提供双 Runtime 认领压力测试。因此以下竞争分析是针对未来共享工作区扩展的边界分析,而非断言当前单 Runtime 本地模式存在故障。
这个边界仍然重要,因为在公共 FCoP 路径中,claim_task 首先读取 TASK 是否仍在 inbox/ 中,然后原子提交实现在 active/ 中用 os.replace() 发布临时文件。如果未来设计允许 agent A 和 B 作为独立认领者,且两者都在源文件被删除前通过了"仍在 inbox"的检查,则两者都可以从相同的旧内容构建认领事件。A 可以先发布;B 可以稍后发布。POSIX 风格的替换允许后来的目标名称替换之前的名称,而两个调用者都可能认为自己的调用成功并开始工作。
这不会将一个有效的串行依赖图变成真正的并行分支。它造成了一种更危险的假并行:一个应该只有一个执行者的工作项启动了两个 agent 会话。磁盘可能只保留后来的 active/ 文件,但这无法撤回第一个 agent 已开始的那个工具调用或代码修改。
当前的 write-and-replace 路径因此解决了"不要读取半文件";它没有为未来多 Runtime 共享工作区提供排他认领证明。公共规范和检查的材料没有提供同 TASK 双重认领压力测试、非可替换认领保留、租约或心跳回收的证据。本文不得将它们描述为现有功能。如果未来设计明确允许竞争认领者,认领入口点需要一个独立的互斥原语:例如,非可替换的排他保留(O_CREAT | O_EXCL,在支持的情况下),或 Runtime 端针对规范任务身份的序列化/比较并交换。该原语必须针对 Windows、本地文件系统和网络文件系统分别验证;link()、文件锁或 rename 的本地语义不能被泛化为跨平台保证。
即使一个正确的排他原语也只回答谁赢得了物理竞赛。它不决定谁有资格竞争、哪个策略版本授权了认领,也不决定失败者应该等待、被拒绝还是进入调解。这些都是治理语义。因此,作为一个工程补丁添加的锁不得悄无声息地创建一个新的授权规则。
一个最低限度可信的认领测试同时针对同一个 TASK 启动两个认领。只能有一个调用者收到可执行的认领凭证。失败者必须收到一个确定性的"已被认领/竞争失败"结果,且不得启动模型会话或工具调用。
一旦 TASK 处于 active,文件系统状态机说明它已被认领。代码生成、工具挂载、测试和输出捕获属于工程运行时。
CodeFlowMu V1.9.7 候选父级实现通过共享命令内核路由任务变更。一个请求绑定 task、root、thread、round、expected revision 和一个幂等键。以下是从私有父提交 2c901972df79dc8d0a1e2eee66ed8dce5e4f953f 中摘录的结构化读取片段,不是 CodeFlowMu Open,无法公开克隆。它只保留以下解释的绑定字段;省略的字段既不是缺席的证据,也不是任何能力声明的依据。
type TaskCommandRequest = {
task_id: string;
root_task_id: string;
thread_key: string;
expected_revision: string;
round_id: string;
idempotency_key: string;
};
接下来三个保护措施。
第一,task、root 和规范 thread identity 必须一致。V1.9.7 规范化账本查询后缀,以免将 lineage bucket 误认为第二个任务标识:
export function canonicalThreadKey(value: unknown): string {
return String(value ?? "").trim()
.replace(/#TASK-\d{8}-\d{3,}.*$/i, "");
}
其次,expected_revision 基于过时事实拒绝写入操作。如果 PM 准备好了针对修订版 A 的操作,而任务已经演进到修订版 B,则旧操作不能不加改变地应用。
不要将一个接口字段变成未经检验的算法。检查过的私有父级证据只能证明一条命令绑定了 expected_revision 并对其进行检查;它不能披露该值是由内容摘要、单调版本、事件序列还是其他规范化方案产生的。因此,本文将其视为当前任务版本的前置条件令牌,而不是基于 mtime 的机制;文件系统修改时间无法承载因果版本化。对于任何打算使用此类令牌拒绝过时操作的实现,最低的工程要求是将其绑定到可以改变该操作有效性的版本事实,并拒绝不匹配;它不应尝试从壁挂时钟时间推断跨进程或跨设备的因果关系。这是本文的一项设计要求,而非对 V1.9.7 未公开算法的声明。
这也意味着目前还没有可评估的版本化闭包。如果令牌覆盖了整个 TASK 内容,那么附加一个 transitions 事件是否会对并发命令造成不必要的过期?如果只覆盖业务内容,那么证据引用或授权变更能否规避过时操作检查?当前材料无法回答这些问题。要测试该设计,需要在固定任务上分别更改 body、transition、证据引用和授权范围,然后重放旧令牌并观察哪些更改使命令失效。在这些结果存在之前,不能声称该字段解决了乐观并发控制或错误中止问题。
第三,幂等性密钥将传输重试与新的业务意图区分开来。在同一密钥下重放相同意图会返回现有结果;为不同意图重用密钥则会产生冲突。这减少了重复的任务、尝试和调度创建。它并不能证明每个外部工具效果都是精确一次的执行。
假设 QA 依赖于 DEV 的交付。PM 创建两个不同的子任务,并将一个显式的 DEV 依赖放置在 QA TASK 上。CodeFlowMu 的调度器可以保留依赖工作,直到上游任务产生所需的完成返回。
正确的含义是"QA 尚未就绪",而非"QA 失败了"。过早唤醒 QA 并强制其撰写被阻塞的报告,会将调度错误制造为业务失败。
依赖关系还必须引用当前的子任务。一个线程可能包含多轮 DEV 返工。旧一轮中最近完成的 DEV 任务不能用来满足新的 QA 契约。
还有一个不能跳过的问题:依赖循环。如果 A 等待 B,而 B 又等待 A,队列并没有创造出答案。检查过的 V1.9.7 材料证明了显式依赖的等待和释放;但它没有证明完整的 DAG 检查。将循环检测时的自动异常暂停描述为当前功能是不准确的。
静态准入检查也不够。运行中的智能体可能会提议下游依赖变更,但默认情况下它不能重写现有的 TASK 图。依赖创建或变更属于 PM、ADMIN 或由活动治理策略明确委托的参与者。已批准的变更创建一个新的任务修订版,记录参与者和策略版本,并在调度继续之前重新运行身份、范围和循环检查。
超时可能报告策略窗口被超出;但它不能猜测应该删除哪条边,也不能宣告业务失败。当前材料没有证明依赖变更授权、动态 DAG 重新验证、死锁超时或循环打破协议的普遍执行。未来的调度器测试必须将未授权的边写入和包含循环的依赖图作为明确的拒绝案例:无论循环是预先提交、在执行期间引入,还是伴随长期缺乏上游进展,结果都应该是授权参与者可检查的问题——而不是无限等待或启发式地选择分支。
开发智能体提交一份绑定到当前任务和执行轮次的 REPORT,包含可检查的代码和测试证据。TASK 然后可以进入审核状态,由授权角色接受或拒绝。
两个分离必须保持完整:
agent 编写的报告中 status: done 是执行者对其工作的声明;
acceptance 是 PM 或 ADMIN 根据当前修订版和证据做出的决定。
TMPA Core Specification S1.0 要求角色、来源和生命周期可以确定性重建。CodeFlowMu V1.9.7 同样将报告和验收建模为不同的事实轴线。报告可以存在而验收仍然待定。
这防止了一种常见的过早完成路径:Runtime 观察到 REPORT-* 并将根任务标为绿色。正确的实现首先验证报告归属、证据和当前修订版,然后将决定交给授权参与者。
任务生命周期不是记录编译器过程每个瞬间的好地方。因此 V1.9.7 将托管命令视为可选的 Runtime 服务。必须存活于会话变更、暴露持续日志、在 Runtime 重启后恢复、或支持精确取消的长时任务可以被持久化管理。简短的测试和构建仍然可以使用宿主机的原生命令工具。不进入托管服务的短命令不会为该服务产生 job.json;其原始输出仍应被记录或引用为 REPORT 证据,但检查过的契约没有规定该载体是附件、链接还是其他形式。
每个托管作业都绑定到任务、会话、尝试和租约信息(时间限定的执行所有权)。其每作业的 job.json 是权威的;聚合索引可重建。重启后,Runtime 可以重新发现运行中或终态的作业,而不是从原始智能体会话的消失中推断业务结果。
微软的 Job Objects 文档提供了一个相关的操作系统概念:进程组可以作为单元管理。它不能证明 CodeFlowMu 使用了每一个 Job Object 设施。它强化了任务生命周期、模型会话生命周期和进程生命周期之间的区别。
特别是,"短命令可以使用宿主机"不能被理解为"短命令已经是可恢复的和可终止的"。托管服务之外的宿主机子进程没有服务编写的 job.json,当前材料也不能证明它统一地被注册到 Job Object、父/子清理树或孤儿进程扫描中。如果智能体会话意外退出,此类命令可能保留文件、端口或工作区。生产部署需要对短命令所有权、超时终止、残余句柄检测和故障清理进行单独测试。在证据存在之前,这是一个风险——而非已交付的能力。
每个工作项有一个规范的任务标识。
子项明确命名其根和父。
报告不能仅凭线程邻近性或壁挂时钟时间归因。
当前状态从合法生命周期位置读取。
如果同一 TASK 出现在两个阶段中,冲突被保留而不是被猜测消解。
body 字段不能覆盖路径状态。
只接受枚举的生命周期转换。
每次转换产生一个追加型事件。
原子性声明保持在文档化的文件系统边界内。
行动前重新检查角色能力、任务范围和当前修订版。
同一业务命令的网络重试不会制造重复工作。
依赖的智能体在明确的前置条件满足之前不会启动。
执行者不能在没有明确授权的情况下变更依赖图;授权的变更创建新的修订版并重新运行身份、范围和 DAG 检查。
对同一 TASK 的并发声明只允许一个执行者启动;竞争失败者不会因为其本地调用返回就启动模型会话或工具副作用。
REPORT 不自动创建业务验收。
对旧修订版的批准不适用于新修订版。
执行者不能单方面关闭需要独立验收的工作。
这些不变量不能证明报告内容是真实的。它们不能替代沙箱化、代码审查或安全测试。它们回答的是一个更基本的问题:系统是否知道它正在处理哪项工作、该工作处于生命周期的哪个阶段、哪些证据属于它、以及谁可以决定下一步?
任务之所以不能可靠地流转,不是因为文件名取得不够优雅,而是因为状态、历史、执行、报告和验收各自保留了独立的语义,同时又有一条稳定的身份标识将它们连接在一起。这正是文件状态机与工程护栏真正交汇之处。
这个文件状态机也存在一个硬性边界:单主机重命名无法被提升为多主机强一致性,目录时间戳也无法替代因果版本号。保留双阶段冲突并等待授权恢复优先保障的是事实完整性,但这并非一份无人值守的自愈合约:当前的材料并未证明存在租约、心跳、超时回收、写前日志或自动回滚机制。它同样没有覆盖每个崩溃点、外部工具副作用或平台。下一步验证步骤是围绕写入、持久化和重命名进行故障注入,同时包括双声明竞争、过期版本重放、动态依赖循环、短命令孤儿进程以及双阶段冲突的授权恢复。版本文件和实时进程报告为 V1.9.7,但该版本仍为候选版本,直至 ADMIN 做出最终的 RELEASED 决定。
此处描述的双阶段冲突并非独立的恢复发明。它进入的是本系列其他地方使用的同一 unknown_reconcile 处置方式。生产信封仍然需要一个具名的协调负责人、开启时间、截止期限、升级路线和允许的终止结果;在它等待期间,Runtime 不得反复唤醒模型并消耗 Token。已经审查的 V1.9.7 证据尚未证明该完整操作合约。
关于本系列如何区分公开规范、私有代码片段、第一方执行记录和独立材料,详见《工程证据阅读方法》(Digital Employee Works)。以下来源仍仅支持本文中声明的特定主张。
FCoP 3.0 规范和 TMPA Core S1.0 支持对 TASK、REPORT、REVIEW、目录生命周期和可重建溯源的描述。它们不承诺在每个文件系统上都有相同的行为。
POSIX.1-2024 rename() 支持在其声明的边界内对目录条目替换进行原子观察;它不支持关于跨挂载事务、崩溃持久性或强网络文件系统一致性的主张。
Windows Job Objects 文档记录了用于管理进程组的操作系统机制。它们不证明该 Runtime 使用了所有 Job Object 能力。
V1.9.7 图表是来自固定环境的第一方工程证据,而非第三方认证或跨平台可靠性声明。访问时间:2026-08-23。
第一部分:治理、文件状态与工程护栏
第二部分:认领、执行、审查并完成一项任务
第三部分:无未授权管理者的自动化
语言版本:英文原文 · 中文版
研究主页:JoinWell52 研究中心