runtime-verification · git:20261015.2c8093f · 2026-10-15 · sha256 27ef8058f6f2cb9a
runtime-verification git:20261015.2c8093fA
Immutable. This exact content never changes and is served at /api/v1/blob/27ef8058f6f2cb9a.
--- name: runtime-verification description: 在提交或交付非平凡代码改动前,需要确认改动在真实运行面上按预期工作时使用;通过 CLI、接口、界面、公开包入口或代理行为驱动改动路径并留存证据。只改测试、文档或无运行面的类型声明时不触发;定位缺陷使用 systematic-debugging,审查代码使用 requesting-code-review。 --- # 运行面验证 目标是让改动的代码在真实入口上执行,并用捕获到的输出证明它做了声明的事。 测试、类型检查和构建是 CI 的证据,不是本技能的验证步骤;需要它们时单独执行并单独报告。在脚本里直接 import 内部函数再打印返回值,等于自己写了一个单元测试,应用并没有运行。 ## 确定范围 - 在 Git 仓库中先确定完整范围:已提交的分支差异(相对上游或基线分支)和未提交的工作区改动都要看,不只看 `HEAD~1`。报告提交数。 - diff 是事实,PR 描述、提交信息和用户说法是对 diff 的声明。两者都读,不一致本身就是发现。 - 找不到任何改动时说明并停止;不在仓库中时,范围以用户指定为准,未指定就询问。 ## 找到运行面 运行面是用户(人或程序)接触改动的地方: | 改动到达 | 运行面 | 做法 | |---|---|---| | CLI / TUI | 终端 | 执行命令,捕获 stdout、stderr 和退出码 | | 服务 / API | 网络端口 | 发请求,捕获状态码、响应头和响应体 | | 界面 | 渲染结果 | 用浏览器自动化或真实应用操作,截图 | | 库 | 公开导出 | 通过包名导入公开接口写示例,不从 `src/` 内部路径导入 | | 提示词 / 代理配置 | 代理行为 | 运行代理,记录它实际做了什么 | | CI 工作流 | CI 运行 | 触发或读取对应运行结果 | 内部函数不是运行面:沿调用方追到上表中的某一行,在那里观察。 只改文档、测试、无产物的类型声明或不改变行为的构建配置时,报告 `SKIP`,写一句原因,不用跑测试填补。测试与源码混合时只验证源码部分;可以读测试了解预期,但随后要去运行应用。 ## 获取启动方式 1. 先找项目已有的启动或验证入口:仓库根目录和改动所在子目录的技能、`Makefile`、`Taskfile`、`package.json` 脚本、README 和 CI 配置。monorepo 中优先找改动所在包自己的入口。 2. 没有现成入口时,从 README 和构建配置冷启动,限时约 15 分钟。卡住时报告 `BLOCKED`,写明停在哪一步、缺什么。 3. 冷启动成功且用户要求或项目约定沉淀时,把有效的构建、启动和驱动命令补进项目已有文档;已有文档只在它给出的命令失效或缺步骤时修改。 ## 驱动改动 - 用最短路径让改动代码执行:改了参数就带参数运行,改了处理函数就请求那个路由,改了错误处理就触发那个错误。 - 执行前回读计划:如果每一步都是构建、类型检查或跑测试文件,那是在重跑 CI,不是验证;找到能到达运行面的步骤,或报告 `BLOCKED`。 - 端到端走真实入口:用户点按钮,就点按钮,而不是只调用底层接口。各部分单独正常不代表连起来正常。 - 涉及删除、发布、发送或写到工作区外,且没有 dry-run 或安全目标时,不在真实目标上执行;验证周边能验证的部分,并写明哪条路径没跑及原因。 - 隔离共享状态:用 `mktemp -d`、独立端口、独立 tmux socket 等,不与用户或其他会话的进程、端口和锁冲突。 - 工作区里有无关未提交改动时,它们可能掩盖或制造问题;必要时在只应用本次改动的临时 worktree 中验证。 ## 主动试探 声明成立只是一半。在同一运行面上,围绕改动试探作者可能没测的情况,选与改动相关的: - 新参数:空值、重复传入、与冲突参数同用、拼错时错误信息是否指出问题。 - 新接口:错误方法、畸形请求体、缺必填字段、超大负载。 - 改动的错误路径:相邻未改的错误路径是否同样被处理。 - 交互界面:中途中断、调整窗口、粘贴异常输入、快速重复操作。 - 状态与持久化:执行两次、在旧状态上执行、两个会话同时执行。 至少做一次试探。没发现问题的试探也要记录,例如“传入空 `--from`,得到明确错误,退出码 2”。 ## 防止假绿 以下情况不能算通过: - 检查被跳过但仍输出成功; - 代码提前返回导致输出为空,而断言对空结果为真; - 只看了源码或构建日志,没有打开生成物、页面或产物; - 改动路径根本没被触发,例如期望 429 却一直收到 200。 通过必须至少有一个非跳过、非空的用例实际经过改动路径。 ## 报告 ```markdown ## 运行面验证:<一句话说明改了什么> **结论:** PASS | FAIL | BLOCKED | SKIP **声明:** <改动应实现什么;diff 与描述不一致时写出> **方式:** <使用的启动入口或冷启动过程,启动了什么> ### 步骤 1. ✅/❌/⚠️/🔍 <对运行中的应用做了什么> → <观察到什么> <证据:命令输出、响应体、截图或面板捕获> ### 发现 - <运行时注意到的问题、摩擦、意外、diff 与声明的差异、环境问题;每个试探即使通过也列一行> ``` - 构建、安装和检出是准备工作,不列为步骤;测试和类型检查结果不放进步骤。 - 🔍 表示试探;全是 ✅ 没有 🔍 说明只重放了正常路径。 - 证据要能被读者看到:读者无法访问本机文件时,把关键输出内联,截图用可发送文件的工具发出,不只给本地路径。 - 发现栏的门槛放低:运行中让你停顿、绕路或意外的都写;PR 页面上别人已经能看到的 CI 结果或评论不算你的观察。 ## 结论定义 - **PASS**:运行了应用,改动在运行面上按预期工作。测试通过、构建干净、代码看起来正确都不算。 - **FAIL**:运行后不符合预期、破坏了其他功能,或 diff 与声明实质不一致。 - **BLOCKED**:无法到达能观察改动的状态,如构建失败、缺依赖、服务起不来。这不是对改动的判定;报告前先查完改动目录下可能提供运行环境的技能和脚本。 - **SKIP**:没有运行面。 没有部分通过:4 项中 3 项通过就是 FAIL,直到第 4 项通过或有充分解释。输出含糊时判 FAIL 并附原始输出,不自行解读。