母工作流评估、增量与控制台二次开发¶
本篇指导用户二次开发母工作流的评估全家桶、增量修复状态机、受控部署和“工作流构建与评估控制台”。修改对象集中在 tools/workflow_evaluation_control/ 及根评估/增量配置,不是某次评估报告或子工作流源码。
二次开发目标¶
典型任务包括增加报告类型或 check id、调整严重程度规则、增加审批动作、改变增量 run/batch/attempt、扩展候选 stager/deployer、修改备份恢复策略、增加控制台页面或结构化编辑文件。所有扩展都必须保持旧 JSON 可读、审批来源可追踪、正式文件可回滚和 API 路径受限。
母工作流修改入口¶
eval_*.yaml、inc.yaml和相应 GuideDoc:Agent阶段与任务边界。tools/workflow_evaluation_control/json_store.py:结构化文件 schema、CRUD 和原子持久化。approvals.py:finding/suggestion 决策和 fingerprint。incremental.py、incremental_runs.py:候选、部署、历史和 run 身份。review_server.py、design_editor.py及前端资源:控制台 API 与 UI。uc_tools.py、uc_checkers.py:向母 Agent暴露受控操作和验收。- evaluation split、review UI、write boundary 回归:行为保护。
报告模型¶
评估分项把检查结果和 findings 写入 eval/。用户审批和建议拥有稳定 id、状态、理由、时间和来源。聚合报告保留不同 run 的历史,不能用旧 finding 代表修改后的新评估结果。
结构化文件必须通过存储接口增删查改。需要扩展字段时,应提供默认值和迁移读取,避免控制台因旧工作区缺字段而崩溃。删除条目是显式 API,版本记录删除还要同步管理对应历史文件和引用。
增量运行身份¶
每次 run_inc 先调用 start-inc-run,生成独立 id 和 tmp/inc_runs/<id>/。本轮审批快照、候选文件、检查记录、部署清单和最终状态都关联该 id。Agent 只能读取当前 run 的候选,不能把上一轮残留当成已批准修改。
候选与部署¶
母工作流应提供受控工具把正式文件复制到当前候选目录。修改发生在候选副本,随后运行语法、fixture 和相关 Make 检查。部署器在同一文件系统创建临时文件、保存旧版本并原子替换正式文件,即使原文件普通写位不可用也不依赖原地覆盖。
旧版本保存到 tmp/change_history/,索引记录原路径、备份路径、哈希、时间、run id 和恢复状态。恢复同样是受控原子部署;删除历史记录必须由用户显式触发。
状态机终止条件¶
- 没有已批准目标:正常快速结束。
- 候选检查失败:继续修复候选,不能部署。
- 已部署但
make check失败:立即继续修复或回滚,不能等待新的批准。 - 全部批准目标有变更和证据,回归通过:完成。
- 无法在批准范围内修复:报告阻塞原因和未完成映射后失败退出。
反复执行同一失败命令且状态、文件和证据没有变化属于空转,应停止循环并进入明确的修复或阻塞分支。
控制台扩展¶
后端入口位于 tools/workflow_evaluation_control/review_server.py,结构化设计编辑逻辑位于 design_editor.py。新增页面字段时,先扩展服务端 schema 和校验,再实现前端呈现。文件路径必须从允许清单和工作区根解析,禁止接受浏览器传入的任意绝对路径。
测试重点¶
- 并发写报告不丢数据。
- 旧格式文件可读取和迁移。
- 未批准条目不能进入增量快照。
- 两次增量 run 不共享候选。
- 部署前保存旧版本,恢复后哈希一致。
- 删除版本条目同时维护文件和索引。
- 非法路径、符号链接和越界目标被拒绝。
- 已部署回归失败不会停在 pending。
结构化文件模型¶
评估控制使用固定允许清单管理 eval/ 和 res/。每份文档拥有 format version、revision 和特定集合:评估报告使用 runs,审批和建议使用 items,部署记录使用 entries,审计使用 events。Agent调用工具时传单条 record,不传整个 JSON 文档,避免一次错误覆盖全部历史。
报告 run 包含 run id、contract version、status、时间、目标 revision、checks、findings 和 metrics。finding 包含稳定 id/fingerprint、严重程度、证据、影响和建议。审批通过 source report、run id、source id 与 fingerprint 绑定;源 finding 内容变化后,旧审批不再是 current。
JSON 加载与验证代码分析¶
源码位置:tools/workflow_evaluation_control/json_store.py,符号 load_document() 与 validate_document()。
看似简单的加载函数把“文件不存在”“JSON 格式错误”和“schema 不合法”分开报告。validate_document() 根据 relative path 选择对应结构规则,拒绝 Agent任意创建未知 eval 文件。开发者新增文档类型时必须同时更新允许清单、base document、校验、collection 名、record id、模板、CLI 和控制台。
加载阶段始终验证意味着历史文件损坏会在读取时立即暴露,而不是在下一次 mutation 时悄悄覆盖。错误消息保留行列号,方便用户修复手工损坏,但正常流程仍应通过结构化工具写入。
原子写入与权限代码分析¶
源码位置:tools/workflow_evaluation_control/json_store.py,符号 _atomic_write()。
临时文件统一进入根 tmp/,写入后 flush/fsync,再以 os.replace() 原子替换目标。函数暂时恢复父目录和目标的用户写权限,完成后恢复父目录 mode,并移除 eval 文件的 group/other 写位。这样防止半写 JSON,也解释了为什么直接编辑器可能看到文件只读。
只读不是“永久锁死”:受控存储和部署器可以通过目录级原子替换更新。开发者不能为方便手工编辑而全局 chmod -R 777,那会破坏审计边界。异常分支必须清理 temporary 并恢复权限。
CRUD 与并发代码分析¶
源码位置:tools/workflow_evaluation_control/json_store.py,符号 mutate_document()。
expected_revision 实现乐观并发控制。控制台读取 revision 后提交编辑,如果期间评估 Agent已更新文档,服务端拒绝旧草稿,避免后写覆盖先写。create 拒绝重复 id,update/delete 要求记录存在,upsert 显式允许两者。
每次成功 mutation 递增 revision、原子写入并追加 audit。list/get 返回深拷贝,防止调用者修改内存对象后绕过持久化。新增批量操作时仍要在一次锁和一次 revision 下完成,不能循环调用单项 API 导致部分成功。
审批新鲜度分析¶
源码位置:tools/workflow_evaluation_control/approvals.py,符号 _fingerprint()、decide_item() 和 approval_is_current()。
fingerprint 根据 finding/suggestion 的稳定业务内容计算,而不是只使用 id。审批记录保存 source run 和 fingerprint;增量部署时重新读取当前源对象并比较。如果评估重新生成同 id 但问题内容改变,用户必须重新审批。
批准、拒绝和暂缓是用户决策,Agent不能自行批准自己的 finding。默认回复可以减少输入,但控制台必须允许用户修改。批量审批只应用于用户选中的记录,并为每项保存来源,不应创建一个无法追踪到具体问题的“大批准”。
增量候选与 run 身份¶
每次 start-inc-run 生成 run id,下面再建立 batch 和 attempt。候选 stager 只允许把 workflow/ 中明确目标复制到当前 attempt 的候选目录,并记录源哈希。Agent修改候选而不是正式文件,保证检查失败时不会污染公开工作流。
run id 解决旧候选混用问题;batch 表示一组相关批准;attempt 表示同一批的修复重试。报告、候选、证据和历史都要携带这些身份。不能使用一个长期 tmp/candidate/ 目录覆盖所有轮次。
部署器代码分析¶
源码位置:tools/workflow_evaluation_control/incremental.py,符号 deploy_incremental_changes()。
部署器先验证 workflow_root、mapping、change id、固定 manifest 路径、当前 run 和 current approvals。每个 mapping 必须包含 source、target、approval ids 和 rationale,且所有批准都在本轮授权集合中。随后执行 projected semantics,阻止候选引入新的确定性高风险 finding。
这个检查防止旧审批、伪造 id 或已改变 finding 被部署。mapping 还要引用覆盖它的批准,使 applied changes 能回答“这个文件为什么允许修改”。
备份、原子替换和回滚¶
源码位置:tools/workflow_evaluation_control/incremental.py,符号 _atomic_copy()、_archive_target() 和 _rollback_targets()。
_atomic_copy() 在目标父目录创建临时文件,copy2 保留元数据,再 os.replace。原目标可以是只读文件,因为不是原地写内容。_archive_target() 把替换前文件保存到本次 history/before 相对路径并计算 SHA-256;新建文件记录 existed=False。
批量部署中途失败时,rollback 逆序恢复已有文件并删除本轮新增文件。逆序很重要,因为后面的目标可能依赖前面的目录或配置。回滚也应记录失败;如果回滚本身失败,报告必须升级为严重状态,不能返回普通部署失败。
恢复与删除历史¶
restore_incremental_backup() 查找记录、验证备份路径仍在允许历史根、核对哈希,并在恢复前保存当前正式版本。这样用户恢复旧版后仍能撤销恢复。delete_incremental_backup() 只响应显式用户操作,更新索引并删除无人引用的备份。
版本记录对 Agent默认不可变,是为了审计;用户在控制台明确删除属于受控管理动作。前端按钮、后端 API、引用检查和文件删除必须一起实现,仅移除 UI 条目会留下孤儿文件。
增量状态机和 make check¶
候选检查失败时继续修候选;部署成功后正式 make check 失败时必须继续修复或回滚。此时不能等待新的批准,因为同一批准已经授权了目标,正式文件也已经改变。只有修复需要越出原批准范围时,才回滚并报告需要新决策。
防空转条件应比较状态、候选哈希、检查返回码和新证据。如果连续执行同一命令而这些值都不变,流程应进入修复或阻塞,不再把阶段提示当成新请求重复验证。
控制台后端与结构编辑¶
review_server.py 将 workspace 绑定到 handler,只公开固定 API。design_editor.py 按文件类型提供 editor schema、draft、cross-file validation 和 save。浏览器只能编辑允许字段,服务端重新读取原 revision、应用 draft、验证所有候选,再原子保存。
工作流文件树阅读 API也要限制路径、符号链接、大小和二进制类型。无固定 schema 的文件只读显示原文;不能为了漂亮界面猜字段后写回。新增监控文件时同时更新白名单、artifact parser、前端 renderer 和 API 回归。
故障场景与测试¶
需要覆盖:损坏 JSON、revision 冲突、重复 id、审批过期、候选越界、目标越界、备份哈希不符、第二个 run 使用旧候选、批量部署中途失败、回滚失败、只读目标、历史恢复与删除、部署后回归失败。每个测试在临时 workspace 中运行,不碰真实业务。
对于控制台还要测试两个工作区端口冲突、已有正确服务探测、非法路径 400、未保存草稿、结构校验失败、批量审批和显式删除。HTTP 200 只证明 API响应,不证明业务状态正确,测试必须重新读取 JSON 和目标文件断言。
五个评估工作流的逐项责任¶
评估全家桶使用五份独立 YAML,拆分目的是限制阅读范围、写入报告和工具权限,避免任何一次静态评估都启动高成本子工作流。
| 配置与 stage | 输入/输出 | 必查内容 | 明确禁止 |
|---|---|---|---|
eval_tools.yaml / evaluate_tool_contracts | 读工具源码、注册、spec、fixture、需求和 res/;写 eval/tools_report.json | 规划工具是否全部存在,是否符合 UCTool 协议,config 是否正确注册,源码是否有真实业务逻辑,fixture/直接调用是否证明可用,是否覆盖用户需求 | 不启动子工作流,不修改 workflow/,不因文件存在就认定工具可用。 |
eval_checkers.yaml / evaluate_checker_contracts | 读 Checker 源码、config args、fixture、stage 产物契约与 res/;写 eval/checkers_report.json | Checker 存在、协议/docstring、class import、构造参数与注册一致,正例通过且单错负例失败,判定是否证明需求,是否引用未来文件或形成无法通过的门槛 | 不为了让现有产物通过而降低业务语义,不直接修 Checker。 |
eval_flow.yaml / evaluate_flow_contracts | 读 config/inc、workflow spec、Tool/Checker/GuideDoc 索引和需求;写 eval/flow_report.json | YAML 可解析只是起点;还要查占位符声明,reference/output 具体且按时可达,Tool/Checker/GuideDoc 可加载,阶段输出支撑后阶段,文档符合真实签名 | 不只搜索 {INPUT} 一种表象,应检查所有未声明变量与引用闭包;不启动子流程。 |
eval_env.yaml / evaluate_environment_contracts | 读 Makefile、setup.py、ucagent_setup.sh、requirements、schema 和环境文档;写 eval/env_report.json | Make 目标和变量优先级,setup 受控更新,requirements 区分 Python/非 Python,路径可移植,秘密不落盘,端口冲突可行动,权限不阻断原子替换 | 不将本机绝对路径成功当作可迁移,不自行修改用户的 res/checkers.json。 |
eval_run.yaml / evaluate_requested_runtime | 读用户指定 runtime target、输入和既有静态证据;写独立 runtime report | 使用 ChildWorkflowSupervisor 启动指定子流程,记录阶段、耗时、失败、产物变化、卡住和终止证据 | 不默认随 run_eval 启动高成本业务流,不在没有超时/终止策略时无限等待。 |
严重度的共享次序是:会令 UCAgent 无法启动、陷入无限重试、破坏/越界替换正式文件或无法回滚的问题为最高风险;产物偏离用户语义却宣称完成紧随其后;确定性检查失效、重要证据缺失和安装不可重现通常是高/中风险;不影响结果的文字和可选改善才是低风险。
增量工作流四阶段逐项说明¶
inc.yaml stage | 主要输入 | 工具与产物 | Checker 与通过语义 |
|---|---|---|---|
understand_generated_workflow | 当前 inc run id、已批准 finding/suggestion 快照、子工作流索引、res/ 索引和直接依赖 | IncrementalContextInventory 产生有预算的 context report,StructuredJsonStore 记本轮状态;先读清单和目标再按需读源码 | generated_workflow_context_complete 只证明足以规划本次修复的初步认识,不要求全部 docs/tools/checkers 已全文读完。 |
plan_approved_changes | 当前批准快照、context report、源文件哈希与相关需求 | 为本 run/batch/attempt 建候选计划,每个 change 映射 approval id、source、target、原因、实现与验收命令;用 stager 复制正式文件 | applied_changes_have_approval 检查计划和后续记录只引用 current approval,未批准建议不能混入。 |
deploy_approved_changes | 当前 attempt 候选、mapping、批准快照、候选检查证据 | 使用 generator 或受控编辑更新候选,检查通过后由 IncrementalChangeDeployer 备份旧版并原子部署,写 applied_changes.json 和 history | approved_changes_deployed、all_current_approvals_deployed 要求每个 current approval 有 deployed/skipped/blocked 映射,不能只因生成计划就通过。 |
verify_and_report_increment | 正式文件、applied changes、history、本轮检查命令与所有 approval 验收条件 | 对正式子工作流运行 make check 和相关目标,失败立即回到候选修复或回滚;通过后写 incremental_report.json 验收证据 | incremental_make_check_passed、incremental_report_complete、incremental_guide_complete、incremental_static_audit_covered 共同证明正式产物通过、报告完整和无越界。 |
批准授权的是“对目标问题的修复范围”,不是“每替换一次文件就再问一次”。正式文件已部署后回归失败,同一范围内的迭代修复不需要新批准,但每次替换必须保存版本和证据。需要改另一个未授权文件时,才应回滚或报告需要新批准。
控制台子系统的二次开发地图¶
“工作流构建与评估控制台”有三类数据界面:评估与审批是结构化 JSON CRUD;构建设计是对有固定 schema 的 YAML 做字段级草稿编辑,对无固定格式 Markdown 只读全文;版本管理是对 change history 做恢复和显式删除。三者不能复用一个“把任意文件变成 JSON 表单”的 API。
review_server.py 负责 HTTP 路由、workspace 绑定、错误码和静态资源;json_store.py 和 approvals.py 负责评估数据;design_editor.py 负责 wfgen/input_example_manifest.yaml、wfgen/workflow_build.yaml、wfgen/requirements_manifest.yaml 等允许字段的 editor schema、draft 和交叉校验;artifact reader 解析实施计划标记、YAML 大纲、JSON 报告和 workflow/ 文件树。服务端必须重新校验每次保存,不能信任浏览器已做过字数和跨文件检查。
新增可编辑字段时,需同步允许字段、值类型、新建/删除规则、字数/统计派生值、跨文件引用、revision 冲突和保存回归。不得开放原始全文覆盖来绕过结构视图。新增只读监控文件时,需更新允许清单、parser、导航大纲、文件大小限制和非法/符号链接路径回归。
继续阅读¶
评估和增量控制的每个不变量都需要确定性回归。请继续阅读测试与回归,了解每个现有回归脚本保护的责任边界。