NemoClaw 维护者状态文件(state.json)Schema 全解析:维护循环的持久化状态设计与实践
2026/9/20 14:03:38 网站建设 项目流程

NemoClaw 维护者状态文件(state.json)Schema 全解析:维护循环的持久化状态设计与实践

【免费下载链接】NemoClawRun agents like Hermes, LangChain Deep Agents, and OpenClaw more securely inside NVIDIA OpenShell with managed inference项目地址: https://gitcode.com/gh_mirrors/ne/NemoClaw

导读

本文围绕 NemoClaw 仓库中维护者自动化 Skill 的核心持久化机制——.nemoclaw-maintainer/state.json状态文件——展开,完整解读其 JSON Schema 的每个字段、取值约束与写入规范,并结合 state.ts、triage.ts、hotspots.ts 等源码,说明该文件如何在 triage、merge-gate、hotspot 检测与每日维护循环之间传递状态、排除项与历史记录。读完本文,你将掌握这份状态文件的完整结构、每个字段的语义与边界条件,以及如何在日常维护流程中正确读写它。

状态文件的定位:维护循环的“单一事实来源”

NemoClaw 的维护者 Skill(如nemoclaw-maintainer-day)以一个可重复执行的维护循环为核心:每天对面向发布的 PR 与 Issue 执行一次“检查版本进度 → 选择一个动作 → 执行 → 汇报进度”的完整流程(见 SKILL.md)。为了让循环在多次运行之间保持连续性——知道哪些 PR 被永久排除、上一次 triage 队列长什么样、当前正在处理什么工作——维护者工具链需要一个跨进程、跨运行持久化的状态文件

STATE-SCHEMA.md(即 STATE-SCHEMA.md)正是这份状态文件的事实性规格说明。其核心约定有三条:

  • 存储位置:状态存放在.nemoclaw-maintainer/state.json(相对仓库根目录)。
  • Git 排除:通过.git/info/exclude.nemoclaw-maintainer/目录排除出版本控制,避免本地维护状态污染提交历史。这一点在 state.ts 的ensureExclude()中得到落实——脚本会在init时检查.git/info/exclude是否已包含.nemoclaw-maintainer/条目,没有则追加。
  • 自描述版本:文件带有version字段,便于未来 Schema 演进时进行迁移判断。

完整 Schema 示例

STATE-SCHEMA.md给出了状态文件的完整骨架,这是所有字段的权威参考。完整 JSON 如下(含默认值):

{ "version": 1, "repo": "NVIDIA/NemoClaw", "updatedAt": null, "priorities": [ "reduce_pr_backlog", "reduce_security_risk", "increase_test_coverage", "cool_hot_files" ], "gates": { "greenCi": true, "noConflicts": true, "noMajorCodeRabbit": true, "testsForTouchedRiskyCode": true, "autoApprove": true, "autoPushSmallFixes": true, "autoMerge": false }, "excluded": { "prs": {}, "issues": {} }, "queue": { "generatedAt": null, "topAction": null, "items": [], "nearMisses": [] }, "hotspots": { "generatedAt": null, "files": [] }, "activeWork": { "kind": null, "target": null, "branch": null, "goal": null, "startedAt": null }, "history": [] }

这份示例与 state.ts 中defaultState()函数生成的默认状态完全一致,说明文档与实现保持了同步,你可以把它当作“初始化后的初始状态”。

顶层字段逐一解读

versionrepo

  • version:Schema 版本号,当前为1。它标识状态文件的格式版本,供读取方做兼容性判断。
  • repo:目标仓库标识,默认NVIDIA/NemoClaw。triage 等脚本会用它拼装gh查询参数(如gh api repos/${repo}/pulls),详见 triage.ts。

updatedAt

最近一次状态写入的 ISO 时间戳。每次saveState()都会把它刷新为new Date().toISOString()(见 state.ts),用于判断状态的新鲜度。初始值为null,表示尚未写入过。

priorities

维护工作的优先级数组,默认包含四个枚举值,体现了维护者循环的关注重心:

优先级键含义
reduce_pr_backlog减少 PR 积压
reduce_security_risk降低安全风险
increase_test_coverage提升测试覆盖
cool_hot_files为热点文件“降温”(降低冲突与改动集中的文件热度)

从源码结构看,这一数组主要作为维护者决策的参考优先级列表;实际的动作选择则由 SKILL.md 中“Step 2: Pick One Action”的有序决策链(approve → salvage → security → test gap → conflicts → sequencing)驱动。

gates:合并闸门开关

gates对象用一组布尔值描述维护循环的自主行为边界,这是整个状态文件中约束性最强的部分:

字段默认值语义
greenCitrue要求 CI 全绿
noConflictstrue要求无合并冲突
noMajorCodeRabbittrue要求无未解决的 major/critical CodeRabbit 问题
testsForTouchedRiskyCodetrue要求触及的“风险代码”有测试覆盖
autoApprovetrue允许自动批准(当所有闸门通过时)
autoPushSmallFixestrue允许在贡献者分支上推送小修复
autoMergefalse禁止自动合并

其中两条需要特别注意:

  1. gates.autoMerge必须保持为false。维护循环可以批准(approve)一个 PR,但绝不能合并(merge)它。这与 SKILL.md 的“Never merge”约束以及 MERGE-GATE.md 中“Report that the PR can proceed to a separate merge decision. Never merge in this workflow”的说明完全一致——合并决定必须交给用户。
  2. gates.autoPushSmallFixes是“小修复推送到贡献者分支”的授权开关。SKILL.md 还补充了其前置条件:必须在 CI 与定时自动化评审针对“同一个未变的最新 PR commit”稳定结束之后,才允许推送。

excluded:排除清单

excluded对象包含prsissues两个映射,用于记录被 triage 永久跳过(直到用户手动移除)的条目:

  • 键必须是数字字符串(number string),如"1234",而不是数字。
  • 值必须是{ "reason": "...", "excludedAt": "ISO" }形式,excludedAt为 ISO 时间戳。

triage 在构建队列时会读取该清单并过滤:const excludedPrs = new Set(Object.keys(state?.excluded?.prs ?? {}).map(Number)),随后classified.filter((item) => !excludedPrs.has(item.number))(见 triage.ts)。注意excluded.issues字段在 state.ts 的类型定义中存在,但exclude子命令目前只写入prs(源码注释明确说明“triage only processes PRs”)。

queue:最近一次 triage 输出

queue缓存最近一次 triage 的结果,用于跨运行对比,避免每次循环都重复完整分析:

字段语义
generatedAttriage 输出的生成时间(ISO)
topAction队列中排名第一的动作项
items主队列条目(merge-ready / review-ready)
nearMisses“差一点就绪”的条目(有明确的小修复路径)

该对象由state.ts set-queue子命令从 stdin 读取 triage 的 JSON 输出并写入(见 state.ts):itemstriageOutput.queuenearMissestriageOutput.nearMissestopActionqueue[0]generatedAt优先使用 triage 输出自带的时间戳。triage 输出的完整字段(含rankbucketscorenextActionriskyFiles等)可参见 triage.ts 的QueueItem接口。

hotspots:热点文件缓存

hotspots缓存最近一次热点检测的结果,用于识别最易引发合并冲突的文件

字段语义
generatedAt检测结果生成时间(ISO)
files热点文件条目列表

该对象由state.ts set-hotspots子命令写入,同样从 stdin 读取热点检测脚本的 JSON 输出(见 state.ts)。热点检测算法见 hotspots.ts:它综合30 天origin/main上的 git churn开放 PR 的文件重叠数,按mainTouchCount + openPrCount * 3 + (risky ? (mainTouchCount + openPrCount) * 2 : 0)打分排序,其中 PR 重叠权重 3 倍(作为冲突代理指标)、风险文件额外 2 倍加成,最终输出前 25 个热点文件。检测到的热点会路由到 HOTSPOTS.md 对应的工作流处理。

activeWork:当前进行中的工作

activeWork记录维护者“正在处理但尚未完成”的单项工作,供中断恢复与交接使用:

字段语义
kind工作类型(如 approve、salvage、test 等)
target目标条目(如 PR 编号)
branch涉及的分支
goal目标描述
startedAt开始时间(ISO)

初始状态为全null。从源码结构看,该字段主要服务于跨循环的上下文恢复——SKILL.md 中“Readstate.jsonto avoid repeated context”的说明即与此对应。

history:操作历史

history是一个操作审计数组,记录了每次循环完成的关键动作。每个条目的格式为:

{ "at": "ISO", "item": "PR#1234", "action": "approved|salvaged|blocked|sequenced", "note": "one line" }

约束条件:

  • at为 ISO 时间戳;
  • item标识目标条目,约定为PR#1234形式;
  • action是四个枚举之一:approved(批准)、salvaged(修复抢救)、blocked(报告阻塞)、sequenced(排队序列化);
  • note为一行简要说明;
  • 最多保留 50 条,超出时删除最旧的条目。该上限在 state.ts 的cmdHistory()中有硬性实现:if (state.history.length > 50) state.history = state.history.slice(-50)

历史记录的典型写入方式来自 SKILL.md 的 Step 4:

node --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/state.ts history <action> <item> "<note>"

例如:

node --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/state.ts history approved PR#1234 "all gates passed, approved"

状态文件读写工具:state.ts 子命令速查

仓库提供了配套的 TypeScript 状态管理脚本 state.ts,所有子命令均以node --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/state.ts <subcommand> [args]形式调用。支持七个子命令:

子命令参数作用
init创建.nemoclaw-maintainer/state.json(若不存在)并确保.git/info/exclude包含.nemoclaw-maintainer/
show打印当前完整状态(JSON)
exclude<number> <reason>将 PR 加入永久排除清单,记录原因与排除时间
unexclude<number>从排除清单移除条目(同时清理prsissues
history<action> <item> <note>追加一条历史记录(自动控制 50 条上限)
set-queuestdin 传 JSON从 triage 输出更新queueitems/nearMisses/topAction/generatedAt
set-hotspotsstdin 传 JSON从热点检测输出更新hotspotsfiles/generatedAt

实现细节值得注意:

  • set-queueset-hotspots通过 stdin 读取 JSONreadFileSync(0, "utf-8")),解析失败会向 stderr 报错并以非零码退出(见 state.ts),因此用法是管道形式:
    node --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/triage.ts | \ node --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/state.ts set-queue
  • 每次写入都会自动刷新updatedAt为当前 ISO 时间。
  • excludereason参数支持空格(args.slice(1).join(" ")),因此“原因”中可以包含多词描述。

状态文件在维护循环中的完整流转

结合 SKILL.md 的流程,状态文件贯穿维护循环的各个阶段:

  1. Step 1 检查版本进度:运行version-target.tsversion-progress.ts,前者读取本地最新 semver tag 并 bump patch 得到目标版本,同时扫描带旧版本标签的开放 PR/Issue 作为“stragglers”(见 version-target.ts)。
  2. Step 2 选择一个动作:triage 依据excluded过滤已排除条目,生成queuenearMisses,随后通过set-queue写入状态文件。
  3. Step 3 执行:根据动作类型走 MERGE-GATE.md(批准)、SALVAGE-PR.md(抢救)等分工作流。批准前必须运行受信任的闸门检查器(run-trusted-check-gates.sh)——该检查器本身也被shared.tsRISKY_PATTERNS列为风险文件,改动它需要测试覆盖(见 shared.ts)。
  4. Step 4 汇报进度:重新运行version-progress.ts展示更新,并用state.ts history追加本次动作记录。若目标版本全部完成,可建议进入nemoclaw-maintainer-eveningSkill。

状态文件还服务于/loop集成场景:/loop 10m /nemoclaw-maintainer-day会周期性触发维护循环,此时“Readstate.jsonto avoid repeated context”成为避免重复上下文的关键手段——queuehotspots的跨运行缓存正是为此设计。

实践要点与边界条件

  • 永远不要打开autoMerge:循环的最高权限是 approve,合并是独立决策,必须由用户执行。
  • 排除项是持久化的“硬过滤”:被排除的 PR/Issue 会被 triage 无条件跳过,只有用户主动unexclude才会重新进入队列。因此exclude时应提供清晰的原因。
  • history 是审计线索:每个动作都应留痕,且保持 50 条以内的滚动窗口;旧条目优先删除。
  • queuehotspots是“最近一次”快照:它们只反映最近一次 triage/hotspot 运行,跨运行对比时要注意generatedAt的时间差异,避免用旧快照做新决策。
  • 风险代码的测试闸门testsForTouchedRiskyCodeshared.ts中的风险模式(安装脚本、onboard 逻辑、blueprint、policy/credential/inference 相关路径等)联动——触及风险文件的 PR 必须先有测试,这是批准的前置条件之一。

结语

.nemoclaw-maintainer/state.json虽是一个小文件,却是 NemoClaw 维护者自动化体系的地基:它以gates划定自主边界,以excluded表达人为干预,以queue/hotspots缓存分析结果,以activeWork支持中断恢复,以history留下审计轨迹。理解这份 Schema,就等于理解了维护循环“如何记住自己做过什么、正在做什么、以及被允许做什么”。在实现层面,STATE-SCHEMA.md 与 state.ts 一一对应,是阅读维护者工具链代码时最值得首先掌握的入口。

【免费下载链接】NemoClawRun agents like Hermes, LangChain Deep Agents, and OpenClaw more securely inside NVIDIA OpenShell with managed inference项目地址: https://gitcode.com/gh_mirrors/ne/NemoClaw

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询