Hermes WebUI 变更准则:从四个根因到十条规则,写出一次评审就能合并的 PR
Hermes WebUI 变更准则从四个根因到十条规则写出一次评审就能合并的 PR【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webuiHermes WebUI服务端 Python、浏览器端原生 JavaScript、无构建步骤用一份 docs/GUIDELINES.md 把什么样的改动能在第一轮评审就合并提炼成了可执行的工程准则先理解导致返工的四个根因再用十条规则逐一落实最后在 PR 描述里把证据摆出来。读完本文你能掌握该项目对完整且经过验证的改动的完整定义——包括如何找齐 bug 的所有同族、如何端到端追踪一个权威值、如何让测试真正咬住 bug、以及如何用 PR 描述向评审者展示你的验证边界无论这些改动出自人类开发者还是 AI 编码助手。为什么 Hermes WebUI 需要这样一份准则文档开篇先立了项目的基本盘Hermes WebUI 刻意保持简单——服务端是 Python浏览器端是原生 JS没有构建步骤。[ARCHITECTURE.md](https://link.gitcode.com/i/d047f213ac7a2d761d3ff40460e70e47)与[CONTRIBUTING.md](https://link.gitcode.com/i/c321bb8007cc1072e149da0c8bdf07d3)中反复强调的无 bundler、无前端框架设计约束意味着每一处改动都是直接暴露给使用者的最终代码。这份简单性只有当每个改动都经过界定范围、经过验证、并且是完整的时才能存活。准则文档的定位很明确它区分了一次评审就合并的 PR和来回好几轮才合并的 PR既适用于人类贡献者也适用于 AI 辅助的贡献——文档直言它尤其为 AI 编码代理而写因为下列错误恰恰是代理最频繁、也最自信地犯的那些。文档还给出了一条阅读建议如果只读一部分读四个根因十条规则只是它们各自的执行手段。四个根因一切需要返工的改动都源于此文档第一部分指出几乎所有评审失败的改动都源于以下四个原因之一。贡献者应当在自己提交 PR 之前就识别出这些问题。修了实例而不是修了类Fixing the instance instead of the class。文档称这是最常见的一种。一个 bug 通常不止一处藏身地——同样的错误活在多个调用点、多个后端或代码路径中、伴随的端点里、第二种布局里、多个生命周期出口上。很容易只修掉报告指向的那一行留下同族问题不管。而漏掉的那个往往位于与你正在看不同的维度上第二个后端、一个不寻常的布局、取消路径、多条目情形。把代理指标当成证明Mistaking a proxy for proof。测试通过了代码里包含那个字符串那个分支跑过了我 mock 了它并得到了正确返回值——这些都不能证明用户可见的行为是正确的。一个即使把修复回滚掉它依然能通过的测试等于什么都没测。只对值的内容推理却不管它的生命周期Reasoning about a values content but not its lifetime。值本身是对的却忽略了它何时变陈旧、谁负责清理它、以及它在每一条退出路径成功、错误、取消、替换、收缩、并发访问上会发生什么。资源泄漏、孤儿缓存、陈旧读取、决策用了这个值但动作用了另一个值都活在这个原因之下。让 diff 长到超出任务Letting the diff grow past the task。加入没有被要求的变化或者重新实现代码库已经集中化的东西一个 fallback、一个共享 helper、一个扩展点。多出来的每一行都是新的风险面让改动更难评审、更难信任。第五个根因只适用于可见的改动把控件放在代码所在的地方而不是用户注意力应该去的地方。十条规则根因的逐条执行规则 1修类而不是修实例动手写修复之前先搜索每一个同族——其他调用点、生产者与消费者、备选后端、伴随端点、其他布局、每一个生命周期出口——然后在**共享的咽喉点shared chokepoint**上修复。如果你有意把某一个同族留在范围之外要在 PR 里点名并说明原因。共享函数里放一个守卫是比每个调用方各放一个守卫更小也更正确的改动。文档还强调了对咽喉点的精确定义咽喉点是包含缺陷的最小边界而不是你能够到的最宽边界。修类意味着守护 bug 的每一个同族而不是为了压住一个坏输出就禁用整个阶段或流水线。如果你的修复挡住了比缺陷所占范围更多的东西它就已经长出了任务边界见规则 9。规则 2端到端追踪一个权威值沿input → normalize → decision → action → persist → cleanup追踪这个值并在每个阶段使用同一个已解析的值。不要让做决策的代码看到一个值、执行动作的代码却用到了陈旧或未规范化的值——这种割裂是静默的正确性 bug。在让决策以某个值为依据之前先确认它是权威的在意图发生点写入一个规范的 kind 字段、由动作本身盖章的来源标记、记录在案的 origin——而不是从 id 前缀、内容形状、是否为空或 DOM 状态推断出来。先搜索是否已存在规范字段恰好在你面前的这个用例上成立的推断是守卫在某个同族用例上误报的最常见方式。如果确实不存在权威字段就补一个测试其中包含一个与你的启发式相匹配的相邻用例并且这个用例必须不触发该守卫。规则 3无法确认时封闭失败fail closed并明说凡涉及权限、能力、身份或包容containment的事情只要你不能确认它是安全的就拒绝——不要在不确定性上走宽松分支也永远不要把失败报告为成功。把 unknown、absent、unverifiable 与 allowed 视为不同的状态。在 PR 里写明我无法验证 X是好的工程把它藏起来才是安全和可靠性 bug 得以溜进产品的方式。规则 4编辑之前先枚举状态空间写下这个改动触及哪些维度——入口点、后端、条目数0 / 1 / 多 / 重复、生命周期出口成功 / 错误 / 取消 / 替换 / 收缩 / 拆除、认证开与关、并发两个 profile 或 worker 同时、输入形状空 / 敌意 / 别名——然后覆盖每一个或者有意地将其标记为范围之外。大多数返工轮次都源于一个未被考虑的维度。文档特别提醒这些轴线是通用的而真正咬人的是子系统专属的维度对新贡献者并不显而易见。在编辑陌生子系统之前去找它真实的变体阅读触及同一段代码的已合并 PR 和评审线程判别性的维度每一种会话谱系类型、每一种回放/恢复来源、每一种流响应形状在那里已经被枚举过了。复用那份清单而不是从你手上那一个用例现编一份。从源码结构看docs/rfcs/canonical-session-resolution.md 正是这类先把 URL 路由、query 参数、localStorage、侧栏行、压缩谱系 ID 都归一到同一个规范会话目标的枚举式合同docs/rfcs/README.md 则是这类 RFC 的入口索引。规则 5把输入和检查-使用间隙当作敌意的跨越信任边界的输入可以被精心构造来击穿朴素的检查奇异的分隔符、大小写、YAML 别名、路径穿越。文件系统和进程状态可以在检查它的时刻与使用它的时刻之间发生变化所以要在使用点做校验持有文件描述符/句柄而不是重新解析路径。缓存必须按完整身份来划定范围否则在并发下会跨 profile/会话泄漏。如果你最终使用的东西不是你验证过的东西那么验证毫无价值。这一条在仓库中有直接实现例证api/upload.py 在处理用户上传的压缩包成员时使用open_anchored_create_fd在真实 workspace 根下以 fd 锚定方式创建文件#L309-L314、#L355-L357并在#L676-L685附近注释说明了带O_NOFOLLOW的打开方式如何防住校验之后、使用之前被换入符号链接的竞争窗口——这正是持有句柄、不重新解析路径的落地形态。规则 6测试必须在修复前失败、修复后通过先把新测试对着当前代码跑一遍确认它因正确的原因失败然后才应用修复。断言可观察的行为行更新了、日志里没有那个 secret、请求携带了正确的值——不要断言源码字符串也不要通过一个顶替了被测对象本身的 mock 来断言。如果 bug 在于从多个条目中挑对那一个测试就必须包含多个条目否则它根本抓不住挑错了。文档对复现材料的要求尤为具体当 issue 自带复现会话捕获、脚本、精确步骤、附件时你的测试要加载它本身而不是你基于对它的理解重建的 fixture。修复和测试如果出自同一个对 bug 的错误模型就会fixture 上永远 base-fail、head-pass而真实症状原封不动加载报告者的真实场景才能打破这种默契。复现是任何钉住 bug 形状的东西——可下载的捕获也可以是围栏化的 JSON 结构、字段级触发条件、精确步骤同样具有约束力。把你的 fixture 绑定到那个形状满足它列出的每一个条件并在任何一个条件被违反时让断言失败而不是给 fixture 授予报告里从未有的属性、好让守卫得以触发。只有当 issue 确实没有钉住形状时才自行重建那个形状——并且要说明你做了重建、说明了你的假设。从仓库实践看这类加载报告者真实场景的 fixture 是存在的tests/fixtures/目录下保留了捕获式会话前缀等真实数据如 tests/fixtures/issue5749_captured_session_prefix.json供测试直接加载真实会话结构而非手工重建。测试的运行方式也有统一入口[scripts/test.sh](https://link.gitcode.com/i/105ef425c0e1d6f39b22fa1c17ad4264)会创建/使用仓库.venv把执行钉在 Python 3.11–3.13见脚本中is_supported_python的判断scripts/test.sh并安装缺失的测试依赖AGENTS.md 明确要求本地 pytest 一律走./scripts/test.sh而不是裸的python3或pytest。规则 7为每份状态指名主人并证明它会被释放对你引入的每个资源或变更一条缓存项、一把锁、一次临时 env 修改、一个加载标志、一个 DOM 节点、一个 pending-map 条目证明它在每一条出口上——成功、错误、取消、替换、收缩/清空、拆除——都会被清理或失效而不仅仅是快乐路径。快乐路径测试在结构上看不见这些泄漏。规则 8Fallback 和默认值是合同——扩展机制而不是复制它如果你的改动意味着要在多个平行块里做完全相同的编辑停下来代码库几乎肯定已经有一个机制一个 fallback、一个共享 helper、一个扩展点而你没找到。往那唯一规范的位置上加。文档给出的例子是本地化文案新的用户可见文案只放进enlocale让它搭上已有的 fallback 机制——不要把英文粘贴进每一个 locale 块。仓库源码印证了这个机制static/i18n.js 文件头部注释明确写着非英文 locale 中缺失的 key 会自动回退到英文static/i18n.jsen是规范文案来源其余语言块只维护自己翻译过的 key——新增文案只需写一处。规则 9diff 就是任务且仅此而已只改任务要求改的。你注意到的其他一切都写进 PR 描述的备注里而不是进 diff。打开 PR 之前跑受影响的测试外加一轮相邻测试的更宽扫描不只是你新增的那些并删掉所有不相关的改动。规则 10可见控件在每次未来访问时都要花注意力——据此放置它控件应该放在哪里由它的使用频率和主流聊天应用把等价控件放在哪里决定——而不是由你的 diff 已经在哪里决定。低频的逐条操作属于溢出/⋮菜单全局或数据类操作属于 Settings只有真正天天用的控件才配得上 composer 这类热区的位置。然后目视验证截取桌面和窄视口、改动前与改动后确认没有东西被裁剪、没有触发溢出折叠、没有 hover-only 的交互在触屏上被搁浅。这条规则的具体 UI 判断依据可参阅 docs/UIUX-GUIDE.md 与 DESIGN.mddocs/pr-media/目录中按 PR 编号归档的前后对比截图before/after 各一张正是评审所要求的那类目视证据的实例。在 PR 描述里展示你的工作最快的评审是评审者能够看见上述事项已被处理、而不必自己去发现缺口。文档要求 PR 描述本身携带证据你找到的同族规则 1/4——以及你有意留在范围外的那些。测试确实咬住的证明——你的新测试在修复前失败过。验证运行——受影响的 相邻的测试而不是只有你新加的那些。改动前后的图片桌面 窄视口适用于任何可见改动。你无法验证的东西——一份显式清单。承认缺口没问题隐藏的缺口是等待评审去发现的 bug。谁为真理负责——针对任何仓库不拥有的断言浏览器行为、某个 provider 的 API、一个 registry、一条 OS 惯例。点名那个责任方并检查你的证明是否是对方会接受的那种页内自动化证明的是页面行为不是浏览器没有先把事件吞掉mock 证明的是你的意图不是 provider 的合同合成 fixture 对真实系统什么都不证明。这里的失效模式不是知道自己没能验证而是以为自己验证了。文档的收尾很务实即使只是不完美地遵循这些准则收益也非常大——因为评审者能精确看见你的覆盖停在哪里而不是被迫用困难的方式自己发现。配套文档与验证入口这份准则并非孤立的贡献规范而是仓库文档体系中的一个节点文末明确了它的配套关系AGENTS.md——AI 助手的仓库入口其中的Before you open a PR一节就是这十条规则与PR 描述证据清单的压缩版两者可以对照阅读。CONTRIBUTING.md——贡献风格、验证要求含./scripts/test.sh与 CI 在 Python 3.11/3.12/3.13 上跑同一套件、PR 描述各节Thinking Path / What Changed / Why It Matters / Verification / Risks / Model Used、UI 改动必须附 before/after 图、AI 使用披露等。docs/CONTRACTS.md——面向贡献者的合同/RFC/设计约束索引触及运行时、流式、恢复、回放、压缩等子系统前应先在此定位对应合同。docs/UIUX-GUIDE.md 与 DESIGN.md——规则 10 所依赖的 UI/UX 具体依据。TESTING.md——影响浏览器行为时的手动检查项配合 scripts/test.sh 的自动化入口使用。把四条根因当作自检清单、十条规则当作执行手段、PR 描述当作证据台账就是这份准则给出的完整工作方式它不要求任何额外工具链只要求在提交之前多想一步——把同族找齐、把值追到底、把每条退出路径都想过一遍然后把这些想过的痕迹直接写给评审者看。【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考