news 2026/9/20 8:08:50

NemoClaw CI 故障分类指南:用有界日志与校验产物定位 GitHub Actions 失败根因

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NemoClaw CI 故障分类指南:用有界日志与校验产物定位 GitHub Actions 失败根因

NemoClaw CI 故障分类指南:用有界日志与校验产物定位 GitHub Actions 失败根因

【免费下载链接】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 维护者技能 nemoclaw-maintainer-classify-ci-failure 的使用方法:如何从任意 NemoClaw 检出目录调用classify-ci-failure.mts,对单个失败的 GitHub Actions job 完成分类。你将掌握命令行参数与输出 JSON 结构、日志的有界截取与敏感信息脱敏机制、产物(artifact)的严格校验式读取流程,以及分类器围绕可信子进程边界构建的安全模型,从而把一次 CI 失败快速收敛为可执行的修复建议。

技能定位:一次 job、一份有界证据、一组分类结论

该技能面向 NemoClaw 维护流程中的高频场景:GitHub Actions 上某个 job 失败,需要在不扩散权限、不泄露密钥、不执行可疑内容的前提下,判定失败类型并给出下一步动作。其核心设计目标有三点:

  • 只读不写:脚本全程只使用经过认证的gh读取 GitHub 数据,不执行任何 GitHub 写操作;
  • 有界有据:日志、产物、分页、压缩/解压体积、条目数、路径数、文件读取数全部有上限,输出保持可审计;
  • 安全边界清晰:产物仅作为数据解析、绝不执行,外部命令仅限固定路径的 Bash 与 GNU coreutils,gh只允许在受信目录中解析。

技能元数据定义在 agents/openai.yaml,其默认提示词将该技能描述为“从有界证据中分类一个失败的 GitHub Actions job”,并可由用户显式调用(user_invocable: true)。

快速开始:运行分类器

在任意 NemoClaw 检出目录下直接运行(示例 job id 为占位符,请替换为真实值):

node --no-warnings \ .agents/skills/nemoclaw-maintainer-classify-ci-failure/scripts/classify-ci-failure.mts \ --workdir "$PWD" --job-id <job-id>

脚本入口是 classify-ci-failure.mts,直接执行时解析process.argv并以 JSON 形式输出分类结果(成功路径输出JSON.stringify(..., null, 2)),任何失败路径都会以非零退出码结束并在 stderr 输出一条有界、脱敏的诊断信息。

命令行参数

参数必填说明默认值
--workdirNemoClaw 检出目录,子进程的工作目录当前工作目录(process.cwd()
--job-id正整数形式的 GitHub Actions job ID
--artifact-name需要额外检视的 GitHub Actions 产物名称不读取产物
--max-lines返回日志的最大行数,取值1500的整数120
--clip-mode截断方向,head(保留开头)或tail(保留结尾)tail

从参数解析实现(classify-ci-failure.mts)可以看到若干硬性校验:参数必须以--name value成对出现、不允许重复选项、未知选项直接报错;仓库被固定为NVIDIA/NemoClawjobId必须是^\\d+$且不能为0artifactName必须与自身 trim 后完全一致,且只允许[A-Za-z0-9_. -]{1,200}字符集。--max-lines的正则校验同样只放行 1~500 的整数。

运行环境前提

分类器要求运行在满足以下条件的 Linux NemoClaw 检出中(classifyCiFailure入口会首先检查process.platform !== "linux"并直接抛错):

  • Node.js 22.19 或更高版本(使用node --no-warnings启动);
  • /proc文件系统(用于进程组监控);
  • Bash,以及 GNU coreutils 中的ddstattailwc(按固定绝对路径调用);
  • 已认证的gh,且必须位于受信目录(见下文安全边界)。

分类工作流:元数据 → 日志 → 产物 → 结论

分类器在 classifyCiFailureWithRuntime 中按固定顺序执行四步:

  1. 读取 job 元数据gh api repos/NVIDIA/NemoClaw/actions/jobs/<job-id>,得到 job 名称、run_id、状态与结论,用于后续产物清单定位;
  2. 有界拉取 job 日志:将日志经tail -c 4000000截取到私有临时目录,再tail -n 20000二次收敛,随后按“NemoClaw CI 失败特征签名”正则筛出关键行及其上下文;
  3. (可选)校验式读取产物:当传入--artifact-name时,分页枚举该 run 的产物清单、按元数据体积精确下载 ZIP、经严格解析后提取*.result.json失败记录;
  4. 分类并输出:基于日志文本与产物中的进程信号/超时/退出码证据,产出findingscategoriesnextActions,最终返回 JSON。

输出 JSON 结构

成功(或部分成功)路径返回的结构包含以下顶层字段:

{ "jobId": "123", "repo": "NVIDIA/NemoClaw", "job": { "id": 123, "runId": 456, "name": "CLI tests", "status": "completed", "conclusion": "failure", "url": "..." }, "result": "classified | unclassified | log-error", "categories": ["test-failure"], "findings": [{ "type": "test-failure", "detail": "...", "suggestion": "..." }], "nextActions": ["..."], "artifact": null, "log": { "jobId": "123", "repo": "NVIDIA/NemoClaw", "pattern": "NemoClaw CI failure signatures", "code": 0, "truncated": false, "truncationNotice": null, "truncationReasons": [], "clipMode": "tail", "maxLines": 120, "selectedLines": 83, "returnedLines": 83, "omittedLines": 0, "matchedLines": 6, "stdout": "...", "stderr": "" } }

result的取值语义:有发现时为classified;日志正常获取但没有命中任何已知签名时为unclassified;日志获取本身失败时(log.code !== 0)为log-error,此时只返回 job 与 log 字段,不产生分类结论。注意技能对unclassified的官方态度:它只是“有界证据下的未分类”,绝不等于“不存在已知原因”

日志的有界截取与截断语义

日志读取是整个分类的信息基础,所有边界都硬编码在脚本中:

  • 源头截取gh api .../logs的输出先经tail -c 4000000写入job.log,即源头最多保留 4 MB 尾部字节;
  • 二次收敛tail -n 20000生成job.tail.log,最多 20000 行;脚本用stat -c %swc -l记录字节数与行数,用于判定sourceTruncated
  • 特征筛选:对每一行应用logPattern正则(匹配FAILAssertionErrorTest timed outProcess completedSIGKILLSource-shapeSource architecturegrew byadds JavaScriptNEMOCLAW_npm audit reportdocs-reviewFern validationhadolintshellcheckNemotron等签名),同时叠加NPM_AUDIT_FAILURE_PATTERNNPM_BOOTSTRAP_FAILURE_PATTERN两组 npm 专项正则;命中行的前后各 20 行被纳入上下文;
  • 输出裁剪:筛选结果再经过projectText,逐行最长 4000 字符、总文本最长 4,000,000 字符;随后boundedText--clip-mode收缩到 40,000 字符以内;
  • 截断可审计log.truncationReasons会逐条列出截断来源(source-log-bounded-before-filteringselected-lines-exceeded-maxLinesselected-line-exceeded-4000-charactersselected-text-exceeded-40000-characters),并在truncationNotice中提示“不要假设被省略的日志行无关或不存在”。

此外,子进程 stdout/stderr 的捕获上限为 8,000,000 字符,超限时置overflow标记并在 stderr 追加提示(classify-ci-failure.mts)。

日志分类规则(findings 类型)

分类规则集中在 classify-ci-failure.mts,每条 finding 由type / detail / suggestion三元组构成,最多返回 20 条。主要签名如下:

finding 类型触发特征建议动作
test-failureAssertionError/Test timed out/Failed Tests/ Vitest 失败计数在对应 Vitest 项目中运行失败的测试,检查首个断言或超时
onboard-entrypoint-growthFAIL: src/lib/onboard.ts grew by N line(s).将新逻辑移入src/lib/onboard/,或让入口净增减非正
new-javascript-sourcePR 新增.js源文件新 Node 源码、测试、脚本一律使用 TypeScript
source-architecture-budget“Source architecture budget failed”减少跨边界 import/export,仅在实测债务下降时放宽限额
source-shape-budget“Source-shape test budget” 失败优先行为测试;否则修复文档化的 source-shape 契约
env-var-documentationNEMOCLAW_*环境变量文档门禁失败在要求的参考文档中补充该变量说明,或移除变量
reviewed-npm-auditnpm audit 门禁报告咨询漂移判断是否为实时咨询漂移,或走安全流程更新基线
reviewed-npm-bootstrap固定 npm 归档的身份/完整性被拒绝检查固定 npm 身份与下载归档,不改动咨询例外基线
docs-review-receipt文档作者评审回执失败针对当前 commit 重跑评审并刷新两个隐藏 SHA 字段
docs-validationFern validation/check-docs/npm run docs运行npm run docs并修复路由、frontmatter 或 MDX 错误
hadolinthadolintDL\d{4}Dockerfile 诊断修复诊断,或使用窄范围、经策略批准的 ignore
shellcheckshellcheckSC\d{4}诊断运行针对性 ShellCheck 与 shfmt 检查并修复
advisor-second-opinionPR 评审顾问 job 中的 Nemotron 第二意见失败除非主顾问或维护者确认具体阻塞点,否则仅作参考

这些签名与仓库中真实存在的质量门禁一一对应,例如 source-architecture.mts 维护“源码架构预算”,run.mts 引用src/lib/onboard.ts的入口增长检查,reviewed-npm-audit对应 ci/npm-audit-exceptions.json 的例外基线管理。

产物(artifact)的校验式读取

当传入--artifact-name时,分类器进入产物检查路径,其边界设计如下(classify-ci-failure.mts):

  • 清单分页有界:按per_page=100分页枚举repos/NVIDIA/NemoClaw/actions/runs/<run_id>/artifacts,最多 20 页、最多 2000 个条目;total_count在分页前后必须一致,否则判定为分页不完整;同名产物(如重复上传)会被视为歧义并报错,列出前 20 个匹配 ID;
  • 体积有界:产物压缩体积必须 ≤ 25,000,000 字节(25 MB)且与元数据一致;下载流用dd bs=65536 count=381dd bs=1 count=30784精确截取 25,000,000 字节,再用dd bs=1 count=1做 1 字节探测,探测到额外字节即判定“超出压缩流限制”;
  • ZIP 严格校验:压缩包字节数须与元数据完全相等,随后交给 readValidatedArtifactZipEntries 解析——该函数完整校验 ZIP 结构(EOCD、中央目录、本地文件头、data descriptor、CRC-32),只接受 store/deflate 两种压缩方式,拒绝符号链接、特殊文件、重复路径、../绝对路径等不安全条目,并在单次调用限制maxEntries(此处为 100)与maxTotalUncompressedBytes(此处为 100 MB)后才返回条目;
  • result.json 有界读取:只提取*.result.json条目,单文件 ≤ 1,000,000 字节、≤ 2000 行;解析出exitCodesignal(须为系统已知信号名)、timedOuterror字段,最多保留 20 条失败记录、20 个畸形路径,并汇总malformedResultCountfilesRead
  • 产物胜出者:多个失败记录按artifactResultRank排序(signal > timedOut > error > 非零 exitCode)选出一个“胜出者”,转换为process-signalprocess-timeoutartifact-reported-errorprocess-exit-code四类 finding 之一,并给出“先检查捕获命令与周边资源证据,再决定是否重试同一 commit”之类的建议。

测试夹具 classify-ci-failure.test.ts 通过伪造ghddwc与真实 ZIP 构造覆盖了上述路径,包括元数据/日志/产物拉取的阻塞与失败注入、重复产物歧义、流超限、FAIL_PROBE_DD/FAIL_PROBE_WC等探针失败场景,验证了有界读取与终止排水(drain)行为。

安全边界:可信子进程与脱敏输出

分类器把自身定义为“内部可信子进程边界”,在 classify-ci-failure.mts 的注释中明确:调用方只能选择固定的gh、Bash 与 coreutils 操作,产物内容仅作为数据解析、从不执行,进程组管理只包含这些可信子进程,而不是不可信负载沙箱。具体机制包括:

  • 固定可执行路径bashddstattailwc固定为/usr/bin/*gh只允许在/usr/bin/usr/local/bin$HOME/.local/bin三个根目录下解析。解析前会逐组件校验:路径根不得是符号链接、每个组件必须是目录/普通文件、不得是符号链接、mode & 0o022必须为 0(组/其他不可写)、属主必须是 root 或当前用户、最终文件必须可执行(X_OK),且realpath结果不得逃出受信根(classify-ci-failure.mts);
  • 环境变量白名单/黑名单:子进程只继承GH_CONFIG_DIRGH_TOKENGITHUB_TOKENHOMELANGLC_ALLLC_CTYPENO_COLORTERMXDG_CONFIG_HOME十个变量,并显式剔除BASH_ENVENVGH_ENTERPRISE_TOKENGH_HOSTNODE_OPTIONSNODE_PATHPATHPERL5OPTPYTHONHOMEPYTHONPATHRUBYOPT等可劫持或泄露凭据的变量(classify-ci-failure.mts);
  • 多层脱敏:所有进入诊断或输出文本的内容都经过redact(),覆盖 JSON 敏感字段、authorization/cookie/set-cookie等请求头、URL 内嵌凭据、X-Amz-*/sig/access_token等查询参数、KEY=value赋值,以及 Slackxox*/xapp-*、OpenAIsk-*、NVIDIAnvapi-/nvcf-、npmnpm_gh[pousr]_github_pat_等独立令牌形态,统一替换为[REDACTED](classify-ci-failure.mts);测试文件在REDACTION_CASES中为这些形态逐一断言了脱敏行为;
  • 私有临时目录:临时文件统一放在/tmp/nemoclaw-ci-classifier-<uid>下(模式0700,运行时校验非符号链接、非组/其他可访问、属主为当前用户),日志与产物分别使用nemoclaw-ci-log.nemoclaw-ci-classify.前缀的mkdtemp子目录;正常与失败路径都会尝试直接删除,删除失败则输出有界、脱敏的rm -rf -- <路径>修复命令并以非零退出;
  • 稳定进程组管理:每条命令都运行在node -e包装的独立、detached进程组下,组领导者在所有后代退出前保持存活(通过轮询/proc统计组内成员);超时先发SIGTERM、1 秒后升级SIGKILL;收到SIGHUP/SIGINT/SIGTERM时拒绝新命令、终止并排空所有自有进程组、同步清理被跟踪目录,并以约定取消码(129/130/143)退出。

失败语义与 GitHub 访问硬停

技能的失败处理契约非常明确(SKILL.md):

  • 任何非零的日志获取结果都是分类失败:清理尝试之后脚本以非零退出、不输出成功 JSON,只报告有界且脱敏的诊断;临时目录删除失败同样导致非零退出并附带直接的删除命令;
  • GitHub 认证/授权失败必须停止:脚本会识别authenticationauthorizationforbiddenhttp 401http 403sso等关键字并抛出专用错误,要求先运行gh auth status,再请用户修正gh访问(含 SSO 或 token scope)后重跑;这一行为与仓库共享规则 git-github-hard-stop.md 一致——不得绕过访问错误、不得改凭据、不得回退到未认证通道;
  • 超时即失败:三类 GitHub 操作各有固定超时(job 元数据 30 秒、job 日志 60 秒、产物读取 60 秒,测试注入可通过timeouts覆盖),超时会先终止进程组再抛“GitHub 不可用,请检查后重试”的错误。

小结:何时使用、如何配合其他维护技能

classify-ci-failure适合作为 CI 排障链的第一步:先用它拿到有界的日志切片、产物失败记录与分类建议,再结合 NemoClaw 仓库中的真实门禁(source-architecture.mts、run.mts、ci/npm-audit-exceptions.json)与 e2e 维护技能 的本地复现手段定位并修复问题。需要特别记住的三条原则:

  1. 证据有界:所有输出都经过截断与脱敏,截断原因随结果返回,阅读时必须结合truncationReasons判断证据完整性;
  2. 只读可信:脚本不做任何 GitHub 写操作,产物永不执行,外部命令全部来自受信路径;
  3. 失败即停:GitHub 访问类失败绝不绕过,先修正gh认证(含 SSO/token scope)再重试;unclassified只代表有界证据下未命中已知签名,不代表不存在根因。

【免费下载链接】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),仅供参考

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

从零搭建每日工作自动化:AI智能体+WorkBuddy完整实战指南

你有没有算过&#xff0c;每天早上打开电脑后&#xff0c;在各个后台、邮箱、报表之间来回切换&#xff0c;到底要花掉多少时间&#xff1f;我自己认真统计过一次&#xff0c;光是拉数据、整理格式、写日报这几件事&#xff0c;每天至少吃掉40分钟。后来我把这一整套流程全部交…

作者头像 李华
网站建设 2026/9/20 8:06:49

AI Coding落地实践:从个人提效到组织效能的关键路径

1. 先看清问题&#xff1a;为什么“个人提效”攒不成“组织提效”先聊一个我在很多技术团队里都看到过的现象&#xff1a;AI 编程助手刚铺开的时候&#xff0c;大家都很兴奋&#xff0c;因为个人体感是真的好。写个单元测试、补个注释、查个不熟悉的 API 用法、解释一段老代码的…

作者头像 李华
网站建设 2026/9/20 8:00:21

8大AI论文工具助力本科生高效学术写作

1. 学术资源获取的痛点与解决方案作为一名经历过本科论文写作的过来人&#xff0c;我深知学生在学术资源获取上的困境。图书馆纸质资源有限&#xff0c;专业数据库价格昂贵&#xff0c;外文文献获取门槛高&#xff0c;这些因素常常让本科生在论文写作初期就陷入困境。而AI技术的…

作者头像 李华
网站建设 2026/9/20 7:58:56

自考论文写作利器:8款AI工具实测推荐

1. 自考学术写作的AI工具革命作为一名自考过来人&#xff0c;我深刻理解论文写作过程中的三大痛点&#xff1a;文献检索效率低、写作框架混乱、格式规范难把握。去年帮表弟备考时&#xff0c;我系统测试了市面上28款AI写作辅助工具&#xff0c;最终筛选出8款真正能提升自考论文…

作者头像 李华
网站建设 2026/9/20 7:57:41

GitHub Trending日榜实战:如何快速评估开源项目

每天早上打开 GitHub Trending 页面已经成了我雷打不动的习惯。不管手头有没有具体需求&#xff0c;我都会先扫一眼当天的热榜&#xff0c;看看今天社区在为什么项目疯狂点 star。2026-09-13 这天的日榜很有意思&#xff0c;榜单不再是清一色的大模型套壳应用&#xff0c;而是冒…

作者头像 李华