news 2026/9/10 1:28:49

OmX autoresearch 候选交接(candidate.json)契约:thin-supervisor 决策边界与 Parity 测试实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OmX autoresearch 候选交接(candidate.json)契约:thin-supervisor 决策边界与 Parity 测试实战

OmX autoresearch 候选交接(candidate.json)契约:thin-supervisor 决策边界与 Parity 测试实战

【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex

导读

本文围绕 OmX(oh-my-codex)仓库中missions/candidate-handoff这一 autoresearch 试点任务,系统拆解其核心目标:实现并验证以仓库根目录为锚点的candidate.json候选交接(handoff)机制,让"薄监督器(thin-supervisor)"能够依据一个显式的、可测试的候选工件做出 keep / discard / reset 决策。读完本文,你将掌握 candidate 工件契约的全部字段与取值语义、supervisor 决策状态机的分支规则、score_improvementpass_only两种保留策略的区别,以及如何用仓库中的 parity 测试验证整条链路。

一、任务背景:thin-supervisor autoresearch 循环需要什么样的交接?

missions/candidate-handoff/mission.md描述了一项明确的工程任务:

Implement and validate repo-rootcandidate.jsonhandoff for the thin-supervisor autoresearch cycle.

其两个主要目标分别是"每次运行的候选工件契约(per-run candidate artifact contract)"和"keep/discard/reset 决策入口(keep/discard/reset decision entrypoint)";成功标准有三条:

  1. 候选交接工件是显式(explicit)且被测试覆盖的;
  2. 运行时能够区分candidate / noop / abort / interrupted四种状态;
  3. parity 运行时测试全部通过。

所谓"thin-supervisor",指的是监督者本身不负责实现实验逻辑,它只负责编排:准备 git worktree、注入指令、等待实验会话写回候选工件、运行 evaluator、根据结果决定保留或回滚。会话与监督者之间的唯一信息通道,就是candidate.json这个候选工件——这正是一个典型的"控制面与执行面解耦"设计:执行会话在一个隔离的 git worktree 中工作,监督者在仓库根目录下读取并裁决结果。

二、运行产物结构:candidate.json 在哪个位置、与哪些文件协同

src/autoresearch/runtime.tsprepareAutoresearchRuntime(runtime.ts)可以看到,每次运行会在仓库根目录下建立如下目录与文件(runId形如missions-demo-20260314t000000z,由 mission slug 与运行时间戳拼接而成):

文件路径(相对仓库根目录)作用
manifest.json.omx/logs/autoresearch/<run-id>/manifest.json运行清单:baseline/last_kept commit、keep_policy、evaluator 契约、运行状态
bootstrap-instructions.md.omx/logs/autoresearch/<run-id>/bootstrap-instructions.md注入给执行会话的指令,含候选工件契约与 supervisor 语义
candidate.json.omx/logs/autoresearch/<run-id>/candidate.json核心交接工件:会话写回,监督者读取裁决
iteration-ledger.json.omx/logs/autoresearch/<run-id>/iteration-ledger.json迭代账本:baseline 与每次迭代的决策记录
latest-evaluator-result.json.omx/logs/autoresearch/<run-id>/latest-evaluator-result.json最近一次 evaluator 的原始结果
results.tsvworktree 根目录下面向人读的 TSV 汇总:iteration commit pass score status description

missions/README.md也明确建议运行完成后检查.omx/logs/autoresearch/<run-id>/下的manifest.jsoncandidate.jsoniteration-ledger.json三个文件来观察 supervisor 的 keep/discard/stop 决策——这与源码中的落盘路径完全一致。

三、candidate.json 工件契约:字段与取值语义

候选工件的类型定义位于 runtime.ts 的AutoresearchCandidateArtifact

export interface AutoresearchCandidateArtifact { status: AutoresearchCandidateStatus; // 'candidate' | 'noop' | 'abort' | 'interrupted' candidate_commit: string | null; base_commit: string; description: string; notes: string[]; created_at: string; }

各字段语义如下:

字段类型必填语义与约束
status枚举字符串必须是candidatenoopabortinterrupted之一
candidate_commitstring | nullstatus=candidate时必须为非空 commit;须能在 git 中解析且与退出时 worktree HEAD 一致
base_commitstring会话开始编辑前的基线 commit;必须与 supervisor 提供的 last_kept_commit 一致
descriptionstring一行简短摘要
notesstring[]短字符串数组,用于携带额外说明
created_atstringISO 时间戳

prepareAutoresearchRuntime在启动时会先写入一个占位工件(runtime.ts),保证文件在会话真正写入前就存在:

{ "status": "noop", "candidate_commit": null, "base_commit": "<baseline-short-commit>", "description": "not-yet-written", "notes": ["candidate artifact will be overwritten by the launched session"], "created_at": "<ISO timestamp>" }

这份占位 JSON 会被注入指令文件,明确告知执行会话"候选工件稍后将被覆盖"。

四、四种候选状态与 supervisor 语义

buildAutoresearchInstructions(runtime.ts)把候选工件的契约逐条写入bootstrap-instructions.md,其中 supervisor 侧语义如下:

  • status=candidate→ 运行 evaluator,随后 supervisor 决定keep 或 discard,discard 时可能对 worktree 执行 reset;
  • status=noop→ supervisor 记录一次 noop 迭代并重新启动下一轮;
  • status=abort→ supervisor停止整个运行
  • status=interrupted→ supervisor先检查 worktree 安全性,再决定如何继续。

这四种状态在processAutoresearchCandidate(runtime.ts)中分派:

  • noop:写入 ledger,更新 manifest,重新生成指令,返回noop,循环继续(countTrailingAutoresearchNoops会统计末尾连续 noop 次数,供上层决定何时收敛);
  • abort:写入 ledger 后调用finalizeRun将 manifest 置为stoppedstop_reason='candidate abort',返回abort
  • interrupted:先调用assertResetSafeWorktree校验 worktree 干净程度——若被脏文件阻塞,则运行进入failedstop_reason='interrupted dirty worktree requires operator intervention');若干净则记录一次interrupted迭代并继续等待下一轮。

五、工件完整性校验:防伪造、防错位

监督者不会盲信会话写回的 JSON。在processAutoresearchCandidate中,读取工件后先经过两层校验:

第一层:结构解析parseAutoresearchCandidateArtifact(runtime.ts)要求工件必须是合法 JSON 对象,status必须是四种枚举之一,candidate_commit为 string|null,base_commitdescriptioncreated_at为非空字符串,notes必须是字符串数组;任何一项不满足都会抛错并使本轮进入error失败态。

第二层:git 完整性validateAutoresearchCandidate(runtime.ts)做三重核对:

  1. base_commit必须在 git 中可解析(git rev-parse --verify);
  2. 解析后的base_commit必须等于 manifest 中的last_kept_commit——防止会话从错误基线出发;
  3. status=candidate时,candidate_commit必须非空、可解析,且必须等于 worktree 当前 HEAD——防止会话虚报 commit。

任何一项失败都会调用failAutoresearchIteration:记录error行到 results.tsv 与 ledger,并将整个运行置为failedstop_reason给出可行动的诊断信息(如candidate base_commit does not match last kept commitcandidate status requires a non-null candidate_commit等)。测试runtime-parity-extra.test.ts专门覆盖了"缺失候选文件、候选 commit 为空、base_commit 不匹配"三类失败路径。

六、决策入口:decideAutoresearchOutcome 的完整分支

决策核心函数是decideAutoresearchOutcome(runtime.ts),它把"候选状态 + evaluator 结果 + keep_policy"折叠为一个最终决策。完整分支如下:

条件决策keep?决策理由示例
status=abortabortcandidate requested abort
status=noopnoopcandidate reported noop
status=interruptedinterruptedcandidate session was interrupted
evaluator 缺失或status=errordiscardevaluator error / 崩溃或解析失败
pass=falsediscardevaluator reported failure
keep_policy=pass_only且 pass=truekeeppass_only 策略直接接受
score_improvement且无可比分数ambiguouspass 但无数值分数,无法比较
score_improvement且新分数更高keepscore improved over last kept score
score_improvement且分数未提升discardscore did not improve

关键设计在于score_improvement策略对"可比分数"的坚持:只有当last_kept_score与本次score都是数值时才可比较(comparableScore),否则即便 evaluator 报了pass=true也会判为ambiguous并丢弃——这避免了无基准的分数被误认为改进。

keep_policy 的两种取值

AutoresearchKeepPolicy定义于 contracts.ts,由 sandbox.md frontmatter 的evaluator.keep_policy声明,缺省值为score_improvement(见 runtime.ts):

  • score_improvement(默认):要求新分数严格高于最近保留分数,强调可量化改进;
  • pass_only:只要 evaluatorpass=true即保留,适合无连续分数语义的布尔验证。

contracts.tsparseKeepPolicy会做大小写与空白归一化,非法取值直接报错(keep_policy must be one of: score_improvement, pass_only)。

keep 之后的 reset 语义

决策为discardambiguous时,监督者调用resetToLastKeptCommit(runtime.ts)执行git reset --hard <last_kept_commit>;但在 reset 前必须通过assertResetSafeWorktree(runtime.ts),它只容忍四类未跟踪的运行时文件(results.tsvrun.lognode_modules.omx/,见AUTORESEARCH_WORKTREE_EXCLUDES),任何其它脏文件都会以autoresearch_reset_requires_clean_worktree:<worktree>:<文件列表>抛错,防止静默丢失会话产物。

七、evaluator 契约:sandbox.md 与结果解析

候选是否被保留,最终由 mission 的sandbox.md中声明的 evaluator 说了算。missions/candidate-handoff/sandbox.md的 frontmatter 即是一个规范示例:

--- evaluator: command: node scripts/eval-candidate-handoff.js format: json ---

contracts.ts 的parseSandboxContract对 frontmatter 有硬性校验:

  • 必须以 YAML frontmatter 开头(---包裹);
  • evaluator块必须存在;
  • evaluator.command必填;
  • evaluator.format必填且 v1 中只能是json
  • evaluator.keep_policy可选,取值限定为score_improvement | pass_only

evaluator 的输出由parseEvaluatorResult(contracts.ts)解析:

  • 必须是合法 JSON 对象;
  • pass必须为布尔值;
  • score可选,出现时必须是数值。
{ "pass": true, "score": 87.5 }

运行时通过runAutoresearchEvaluator(runtime.ts)以 shell 方式在 worktree 内执行 evaluator 命令,捕获 stdout/stderr 与退出码;退出码非 0、输出非 JSON、pass缺失、score非数值都会归一化为status='error'的记录,并最终映射为discardevaluator error)决策。

八、测试覆盖:三份测试如何锁定契约

任务成功标准的第三条"parity runtime tests pass"对应src/autoresearch/__tests__/下的三份测试:

runtime.test.ts—— 运行时主链路:

  • 验证 bootstrap 指令包含"exactly one experiment cycle"、evaluator 契约(required output field: passoptional output field: score)与迭代状态快照;
  • 验证.omx运行时文件被视为 reset-safe;
  • 验证prepareAutoresearchRuntime落盘全部产物(mission/sandbox/manifest/ledger/results/instructions)、manifest 字段(mission_slug、branch_name、worktree_path)以及 baseline 行写入;
  • keep/discard 端到端:构造分数从 1 提升到 2 的候选 → 决策keeplast_kept_commit前移;再构造分数回落的候选 → 决策discard且 worktree HEAD 被 reset 回改进 commit;ledger 顺序为baseline → keep → discard

runtime-parity-extra.test.ts—— 边界与异常分支:

  • 并发锁:第二次prepareAutoresearchRuntimeautoresearch_active_run_exists被拒;
  • resume:resumeAutoresearchRuntime可恢复 running 态 manifest,缺失 worktree 报autoresearch_resume_missing_worktree,终态 manifest 报autoresearch_resume_terminal_run
  • ambiguousvskeep:无基线分数 +score_improvementambiguouspass_onlykeep
  • noop/abort分支分别记录并最终停运行;
  • 三例完整性失败(candidate_commit 为空、base_commit 不匹配、候选文件缺失)均进入failed状态并带可读 stop_reason;
  • interrupted、evaluatorpass=false、evaluator 输出非 JSON(解析错误)三条分支的 results.tsv / ledger 记录断言。

contracts.test.ts—— 契约解析单元测试:

  • slugifyMissionName的确定性;sandbox frontmatter 的解析与各类非法输入(无 frontmatter、缺 command、缺 format、format 非 json、非法 keep_policy)的拒绝;
  • evaluator 结果解析:接受{pass:true}{pass:false,score:61},拒绝缺passscore非数值;
  • mission 目录必须位于 git 仓库内、必须同时存在mission.mdsandbox.md

这三份测试共同构成"工件契约显式化 + 状态可区分 + parity 通过"的可执行证据。

九、从 mission 到实战:如何查看与运行

missions/README.md说明这些 mission 目录是"autoresearch-ready pilots",每个目录包含mission.md(目标、范围与预期交付物)与sandbox.md(evaluator 契约与运行边界)。运行后可在.omx/logs/autoresearch/<run-id>/下观察manifest.jsoncandidate.jsoniteration-ledger.json来核对 supervisor 的每次决策。

需要说明当前仓库 CLI 的约束:src/cli/autoresearch.ts表明omx autoresearch命令面已进入hard-deprecated状态,直接 CLI 启动 / resume / run 均会刻意失败,迁移路径是改用$autoresearchskill(hook 原生持久循环,见 skills/autoresearch/SKILL.md)以及$deep-interview --autoresearch(用于在编写 mission 工件前澄清目标)。因此,阅读本仓库时建议以 src/autoresearch/runtime.ts 与 src/autoresearch/contracts.ts 的纯运行时逻辑为准理解契约,以三份测试文件作为可执行的行为规范。

十、小结:候选交接契约的要点清单

  1. 交接载体:仓库根目录.omx/logs/autoresearch/<run-id>/candidate.json,会话写、监督者读,是执行面与控制面的唯一信息通道。
  2. 四态语义candidate进入 evaluator 评估;noop记录后重开;abort停运行;interrupted先验 worktree 安全性。
  3. 双重校验:结构校验(字段类型与枚举)+ git 完整性校验(base_commit 必须等于 last_kept_commit,candidate_commit 必须等于 HEAD)。
  4. 决策收敛score_improvement(默认,需要可比分数提升)与pass_only(布尔通过即保留)两种保留策略;discard 前必须 reset-safe。
  5. 可测试性:基线、keep、discard、noop、abort、interrupted、evaluator 失败/解析错误、完整性伪造,全部有端到端测试断言,构成契约的活文档。

理解了candidate.json这份契约,就等于掌握了 OmX autoresearch 运行时"如何让一个自治实验会话与一个薄监督者安全协作"的核心机制——它把不可信的会话输出转化为可验证、可裁决、可回滚的状态机输入。

【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 1:26:39

电商数据分析工具选型:从BI到数仓与实时流处理的最佳实践

做电商数据分析的朋友&#xff0c;最近被问得最多的一个问题&#xff0c;往往不是某个指标怎么算&#xff0c;而是“我们到底该上什么数据分析工具”。有人刚搭完数据团队&#xff0c;有人已经在几个 BI 里面横跳&#xff0c;还有人花了不少预算把大数据全家桶买齐了&#xff0…

作者头像 李华
网站建设 2026/9/10 1:23:31

SAP年结必看:FAGLGVTR与F.16总账余额结转实操与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华