☰
jevgrep 代码评审技能实战指南:26 条评审原则、执行流程与源码级落地
2026/9/30 12:58:10 网站建设 项目流程

【免费下载链接】jevgrep

Find code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.

项目地址:https://gitcode.com/gh_mirrors/je/jevgrep
点击查看免费下载

导读

本文以 jevgrep 仓库内置的.agents/skills/code-review/SKILL.md文档为主体,系统讲解其面向 AI 编码 Agent 的代码评审方法论:26 条可执行的评审原则,覆盖命名、注释、模块边界、测试质量、认证安全、批处理容错等主题,以及“Review → 分组引用行号 → clean/not-clean 结论”的评审流程。读完本文,你将掌握一套可直接交付给 Agent 的评审 checklist,并了解该技能在 jevgrep 仓库中如何与review、refactor-clean、write-tests等技能协同工作,以及仓库源码中的对应实现证据。


一、技能定位:何时触发、用哪些工具

该文档的元信息(frontmatter)界定了技能的使用边界:

  • 名称(name):code-review
  • 描述(description):用于评审已变更代码的命名、过期引用、不必要的复杂度与注释质量;应在完成实现工作之后、提交之前,或用户要求审查/审计代码时使用
  • 允许工具(allowed-tools):Read Grep Glob Bash——评审者只被允许读取文件、搜索引用、按模式查找文件和执行 shell 命令,不需要(也不应)修改代码

这与 README 中“仓库是只读”的定位一致:code-review是审查者,产出的是带行号的分组问题清单与最终结论,而不是改动本身。修改工作交给refactor-clean(形状)与implement-spec等实现类技能。


二、评审流程与输出契约

文档末尾的Your task定义了评审的硬性执行协议:

  1. 输入:Review: $ARGUMENTS——若未给出参数,则默认评审git diff --staged(暂存区)或git diff(未暂存改动)
  2. 输出要求:
    • 每个发现的问题必须引用文件和行号(cite the file and line number)
    • 按类别分组(Group by category)
    • 以clean/not-clean的明确结论收尾

这个协议保证了评审结果可回溯、可复核。jevgrep 仓库中review技能(.agents/skills/review/SKILL.md)进一步说明了code-review在整个交付流程中的位置:一个完成的变更要经历三道关口——形状(shape)由refactor-clean负责、diff(diff)由code-review负责、文档(docs)由write-docs负责;code-review发现的问题若迫使结构性改动,必须回到refactor-clean重新执行,而不是带病前进。


三、命名与引用的真实性(原则 1–3)

3.1 名字必须反映当前现实

变量名和函数名应描述它们现在是什么(what they ARE),而不是曾经是什么。当底层机制发生变化(文档举例:FUSE → NFS),所有相关命名都必须同步更新。评审时问自己:一个新读者会被这个名字误导吗?

3.2 不允许存在过期引用

重构之后,必须用 grep 搜索对旧方案的引用——遗留的检测逻辑、废弃的功能开关、提到已删除代码的注释。如果某个方案“试过又回退了”,就要清除全部痕迹:代码库应该看起来“当前方案从一开始就是计划”。

3.3 检测逻辑只保留真正必要的一个判断

“这个功能能否运行”这类 gate 应当只检查真正关键的那一个条件。不要串联回退式检测(binary 存在 OR 源码存在 OR 工具链存在),当其中一项检查已能覆盖全部时,其余都是噪音。

仓库佐证:code-review强调的“删除过期路径”在仓库的refactor-clean技能(.agents/skills/refactor-clean/SKILL.md)中被进一步放大为“零谱系命名”(Zero lineage signaling)——名字编码历史(foo-v2、foo-legacy、以实验命名模块)对后来的读者毫无信息量,历史应该留在 git 里,而不是留在标识符里。


四、注释只写 WHY,不写发生过什么(原则 4)

注释质量是评审的核心维度之一,文档给出了明确的正反清单:

保留(Keep)——非显而易见的发现、平台怪癖、“如果删掉这行,X 会因 Y 而坏”:

// com.apple.provenance causes SIGKILL when spawned as child process // umount while server is alive panics the macOS NFS client // NFS client uses cookie verifier to decide if cached readdir is valid

删除(Remove):

  • 试过什么、放弃什么、改过什么名字的叙事:
    • // We changed this from cp to cat to work around the provenance issue
    • // Wrapper added because FUSE-T was zero-padding (see commit abc123)
    • // Previously this was called fuseAvailable but we renamed it
  • 只是复述代码行为、不补充推理的注释
  • 很多时候根本不需要注释(Often no comment is needed at all)

原则 26 补充了一条硬规则:发现的错误注释本身就是缺陷(A comment you discover is false is a defect),必须当场修正——错误的注释比没有注释更危险,因为它会误导所有后来的读者。


五、安装期与运行期分离、消灭中间产物(原则 5–6)

  • 安装脚本负责准备前置条件(工具链、系统依赖);运行时命令负责编译、缓存、二进制管理。两者不得混用——如果安装脚本在编译运行时也要编译的二进制,那么两者必有一方是错的。
  • 在多轮方案迭代后,要审计是否存在“只是垫脚石”的逻辑:为方案 A 加的 workaround,切到方案 B 后必须删除,即使它无害。代码应读起来像是一个早知道正确答案的人从零写出来的。

这条原则在 jevgrep 的 CLI 中有直接体现:jg skill命令(apps/cli/src/skill.ts)把“安装技能”这个职责严格放在安装路径上——它通过npx skills add dzhng/jevgrep --skill jevgrep委托给外部 skills 安装器,而不是在jg运行时逻辑中内联任何安装细节;搜索运行时则完全不触碰安装相关代码。


六、变更之后收紧保证(原则 7)

当某个变更让原本“可能”的事情变成“必然”(变量总是被赋值、文件总是被创建、函数总是返回),必须审计下游代码中仍然防御旧“可能态”的守卫:

  • 冗余的空值检查、回退默认值、对不可能再为 null 的值做if (x)守卫——它们暗示着不存在的可能性,是误导
  • 不再需要重新赋值时,优先const而不是let
  • 绝不压制信号,要修复根因:_前缀的未用参数、// @ts-ignore、eslint-disable、as any都在掩盖真实问题。参数不用就 DELETE,并把删除级联到所有调用方;类型不匹配就修类型。运行检查器、修掉每个错误、重复此过程。跨多文件的机械改动正是 Agent 最擅长的事——不存在“调用方太多”这回事

七、变更纠缠不清时,从干净处重新开始(原则 8)

如果某个文件经历了 3 轮以上相互冲突的编辑,用git restore恢复它,然后只重新应用真正需要的改动。不要试图外科手术式地修补一团乱麻——从干净状态开始更快、更不易出错。


八、测试必须断言真实值,而不是只断言集合大小(原则 9)

测试去重、归一化、幂等操作时,要断言存储后的值,不能只写toHaveLength(1)。长度本身证明不了逻辑正确——一个坏掉的归一化器可能静默丢弃一个输入,或存下两个恰好匹配的不同归一化形式。

标准模式:以格式 A 加入值,再以格式 B 重复加入,然后同时断言“数量为 1”和“存储值等于期望的归一化形式”:

// Bad: passes even if normalization is broken expect(data.phones).toHaveLength(1) // Good: proves normalization recognized both formats expect(data.phones).toHaveLength(1); expect(data.phones[0]).toBe('+12125551234');

仓库佐证:jevgrep 的 CLI 参数测试(apps/cli/test/args.test.ts)正是这一原则的正面实践——它断言解析结果的具体值(root: "-tree"、maxSourceBytes: 12、policy: { hidden: true }),而不是只检查“解析成功”;对于--concurrency它逐项断言非法输入("0"、"-1"、"1.5"、"NaN"、"1e2"、超大整数)都会抛错。配套的write-tests技能(.agents/skills/write-tests/SKILL.md)把这条原则扩展为完整的测试方法论,并补充了“证明测试能失败(falsify once)”“断言设计契约而非当前行为”等进阶要求。


九、无薄封装、无纯转发的模块(原则 10)

如果一个模块只是转发另一个包的函数或类型,删除它,直接导入原包。不要为脚手架代码或未发布的 branch 工作保留本地兼容垫片。纯export * from ...的 barrel 文件没有价值,除非它定义了带项目语义的真实公共边界。优先直接使用上游 API 名,而不是发明discoverAll()这类本地别名去包装loadSkills()。


十、只在真实所有权边界处抽取模块(原则 11)

  • 不要为了减少行数而拆分文件。一个新文件应当拥有读者能命名的一个连贯职责
  • 当模块集中了相关策略、状态转换、资源处理或领域特定行为时,才抽取模块
  • 如果抽取增加了总体间接层却没有厘清所有权,就让代码保持本地化
  • 好的拆分通常能降低原文件的导入压力,因为依赖随职责一起迁移了

refactor-clean技能对此的补充是:约 1000 行以上是一个“气味”而非判决——内聚的状态机、生成表、单一算法可以合理地大;但注册了大量路由、内联处理多个领域的 god-file 就是责任堆积。拆分的对错标准是“每个新模块拥有一个可命名的职责,且导入压力下降”,而不是“行数变少了”。


十一、测试与实现解耦:端到端驱动系统(原则 12)

这是文档中篇幅最长、分量最重的一条原则,核心论点:最有价值的测试套件是与它所覆盖的实现最解耦的那套——解耦到“通过驱动前端来锻炼后端、通过用户走的同一入口来锻炼模块”的程度。戳内部实现的测试冻结了内部;驱动公共表面的测试让你可以自由重构底层一切。

具体的操作准则:

  1. 优先最外层入口点(仍能给出快速、确定性信号的):CLI 二进制 > 顶层导出函数 > 内部 helper > 私有方法。用户调用的是 CLI,就对着 CLI 写测试;用户看到的是 TUI,就通过真实按键命中的同一输入管线驱动它,断言渲染出的帧,而不是中间状态
  2. 测试行为,而非结构:断言可观察结果——退出码、stdout、渲染输出、磁盘上的文件、HTTP 响应、持久化的行。不要断言“哪些函数被调用、什么顺序、什么中间形状”
  3. 通过的测试应意味着真实用户得到正确结果:如果测试在生产路径损坏时仍然通过,测试就接错了线。常见气味:stub 被测对象本身、绕过 router/dispatcher/parser、手工构造生产环境本来会从输入构建的内部事件
  4. 测试装置必须按生产环境的接法接线:生产中总是设置的输入(已定型的 status 流、modal 配置、同样的环境变量)属于契约的一部分,装置里也要传入等价物。如果你只在真实环境里才能复现某个 bug,说明装置跳过了生产环境设置的某个输入——修装置,让下一轮同类回归由测试套件捕获,而不是由用户捕获
  5. 耦合的测试是重构税:重命名一个内部函数或移动模块导致几十个测试失败、却没有改变任何用户可见行为,说明套件测错了层。把那些测试改写到外层表面,删掉脆弱的
  6. 单元测试只留给真正棘手的纯逻辑:解析器、归一化器、调度器、带微妙不变量的状态机。其他一切都值得写成集成或端到端测试

仓库佐证:args.test.ts完全符合“驱动最外层入口点”的要求——它不直接调用内部函数,而是对parseCommand(CLI 参数解析的公开入口)传入用户会敲的原始参数数组(["find behavior", "--hidden", "--no-cache", "--max-source-bytes", "12", "--", "-tree"]),断言可观察的解析结果与错误行为。


十二、失败的检查可能是工具链缺陷,而非代码缺陷(原则 13)

在手写类型、加 cast、钉住值、重构代码去让检查器(类型检查器、编译器、linter、测试运行器、构建)通过之前,先确认失败是代码缺陷还是工具链/环境产物。为迎合损坏或不匹配的工具而改代码,是掩盖真实问题的 workaround——这是“绝不压制信号”规则的上层延伸。

可执行的三条纪律:

  1. 在报告失败的同一工具链下复现——CI/部署的版本和配置,而不是只复现本地的。本地全绿什么也证明不了:pinned 的预发布版、preview 构建、本机与 CI 之间的版本漂移,都可能在相同源码上本地通过、CI 失败(或相反)
  2. 如果相同源码在真实/pinned 工具下通过,代码就是正确的——修复应落在工具链(钉版本、修配置),而不是代码。输出有歧义时,直接探测工具:强制它打印实际计算出的值、类型或错误,而不是猜原因
  3. 保持本地 == CI:确认把关合并/部署的检查跑的是与部署相同的工具链。版本漂移会让每一个绿色检查都存疑,“本地能过”就不再是部署能过的证据

十三、身份来自认证,绝不来自调用方(原则 14)

  • 行动者身份——org/tenant/workspace id、user id、actor——必须从认证请求(API key、session 或验证过的内部 key)解析,绝不能从调用方提供的参数取得。一个从 args 里读actorId/orgId的公共 mutation 是伪造面(spoofing surface),不是功能
  • 唯一例外是可信内部调用:只有当存在有效内部 key 时,才接受调用方提供的 actor;否则从认证推导身份并拒绝提供的 id
  • 要限定到认证范围内的子对象(特定 channel、share、app)时,取子id 并验证它属于认证推导出的父级——不要相信 body 里并行的父 id

十四、公共 API 动作 = 薄认证 + 分发,不内联业务逻辑(原则 15)

公共路由的职责是:认证、校验、推导身份、分发给持有工作的模型函数或内部动作。保持这个包装薄——它是认证/运行时边界。不要把第三方 SDK / 分析 / 邮件逻辑内联进公共边界,哪怕“只有 3 行”,也要推到分发后面。

文档特别给出了 Convex 的实践:不要为了满足一个 action 就给文件加'use node'——那会把文件里所有 action 都推进 Node 运行时。正确做法是拆分:auth+dispatch(默认运行时)→services/<thing>.ts('use node',拥有 SDK 调用)。


十五、公共端点以最小范围发布(原则 16)

一条路由、一次请求一个条目。不要在出现具体的第二个调用方之前,就预先加/batch变体、分页列表或过滤参数。把 schema 内联在路由里;不要把 4 行的 schema 抬到共享的schemas.ts“以备复用”——没人复用时就没有复用。除非 body 真的无界,否则跳过 body 大小上限。


十六、复用既有类型:派生,而非重声明(原则 17)

如果类型已在上游存在(schema 校验器、协议包、生成的 client、SDK),直接使用它——不要内联重声明它的形状,哪怕只是部分。重声明的形状会漂移。变体用派生:

// Bad: redeclares a shape that already exists upstream type UserSummary = { id: string; name: string; email: string } // Good: derive from the existing type type UserSummary = Pick<User, 'id' | 'name' | 'email'>

Convex/Zod 等价物:Infer<typeof V>、FunctionArgs<typeof api.x.y>、z.input/z.output。

原则 22 将这条扩展为更宽的一般规则:必须保持一致的东西需要一个所有者。两个声明各自可以独立变化却又必须保持一致时,它们会漂移——把共享决策放在一个家,让每个使用点从它组合。平行的 enum、picker 列表、复述别处集合的 switch 都是常见病灶。更难的一半:当近亲确实合理地不同时,把差异理由写进代码——未记录的差异与漂移 bug 无法区分,读者分辨不出意图与疏忽。


十七、在索引处过滤,绝不take()后过滤(原则 18)

当列表查询要从表的子桶返回行(active vs. archived、status === X)时,索引必须完成过滤。不要.take(N)未过滤的查询再在 JS 里.filter()你想要的桶。

为什么它坏:.take(N)返回索引顺序头部 N 行。如果头部全是另一个桶的行,post-filter 即使桶里有几百行更老的行也会返回零。take(N*2)只是推迟失败。

正确模式:把判别字段放进索引,用.withIndex(..., q => q.eq(...)),或用q.gt(field, 0)表示“存在”桶(Convex 把undefined排在已定义值之前)。.first()/.unique()与“是否存在任何 X”探测同理。


十八、绝不.collect()——用.take(N)限定读取(原则 19)

Convex 的.collect()无上限地读取每个匹配行。对任何按租户随时间累积的东西(sessions、events、ledger 行、audit 行),第一天还很小的查询最终会在一次 reactive tick 上拉取数千行,悄然拖垮整个客户端的响应性。

  • 用.take(N)替换.collect(),N 是明显高于今天工作集的安全上限(100、1000)——这是对抗病态数据的 cap,不是 UX 分页器。.withIndex(...).filter(...).collect()同理
  • 如果确实需要每一行(迁移、管理端导出、一次性维护),用注释说明,并从可取消的 mutation/action运行,绝不在 reactivequery里跑

十九、不要仅为重命名或补默认值而 map 重映射行(原则 20)

逐字段复制、只为改两个名字或合并undefined → false的对象字面量.map()是噪音,而且新加的列会静默丢失,直到有人更新 map。如果消费者需要全部字段,直接返回行;只要子集,用Pick/Omit或解构-剩余。只有新名字确实澄清含义时才重命名;只有下游确实无法处理缺失时才补默认。

存储专用字段(_id、_creationTime、内部 id)用一次解构-剩余剥掉:

return rows.map(({ _id, _creationTime, ...row }) => row);

二十、内部 API 不携带版本或兼容机制(原则 21)

当生产者和消费者都是我们自己(自有 apps、services、functions)时,不要加protocolVersion字段、版本协商、能力标志或“以防对方更旧”的分支。部署就是版本(Deploying is the version)。

唯一真实的兼容轴是字段而非版本——而且它是不对称的,不是一个旋钮:

  • 严格解析请求(拒绝未知字段)
  • 宽容解析响应/事件(忽略未知字段)

这让生产者可以增加字段而无需消费者同步发版,覆盖了我们实际存在的唯一倾斜(组件各自按自己的节奏更新)。

气味清单:线上 schema 里没人读的版本字面量;if (payload.v >= 2)分支且唯一调用者是我们自己部署的代码;对响应做严格解析——它把每次服务端增量变更都变成破坏性变更。

例外:真正的外部 API(无法重新部署的消费者)在路由上版本化(/v1/),绝不按字段版本化。


二十一、批处理循环隔离单项失败——一个坏项不能饿死其余(原则 24)

任何遍历独立工作项的循环(sweep、cron 批、队列排空、fleet pass、fanout)都必须逐项捕获并继续——把失败收集进结果(failed列表)或记录日志。未捕获的单项 throw 会中止整轮;由于 runner(cron、scheduler、sync rail)下一 tick 会重新选择同一个有序集合,一个确定性失败的项会成为永久队首阻塞:它后面的一切永远重新排队,而指标却显示任务在“重试”。

事务上下文中更糟:未捕获的 throw 还会回滚游标/进度写入,导致同一页无限重跑。捕获错误能保住事务——但失败项 throw 之前的写入会持久化,所以要在写入幂等或可安全重跑的项边界处捕获。

  • 只有失败可证明是批级别的(共享下游不可达)时,提前退出才是正确的;项级别错误永远不是
  • 如果调用方需要失败可见性:捕获-记录-继续,整轮结束后再抛出第一个错误
  • 即使有隔离也要小心排序陷阱:如果成功项留在候选集里(每次重试把阻塞点前的东西全部重新快照),sweep 的选择逻辑也要排除已完成的工作
  • 可接受的形式:逐项 try/catch + 结果中的failed;按项键控的Promise.allSettled;捕获-记录-继续后抛
// Bad: one unreachable VM freezes every candidate behind it, forever for (const ws of candidates) { await archive(ws); await mark(ws) } // Good: the same loop, per-item try/catch pushing { workspaceId, error } onto a failed array

二十二、重命名用户可见内容 = 清扫测试可见的一切(原则 25)

用户可见文案、可访问名称、路由、data-*属性对不在你门禁里的测试层是承重的——live-staging 装置、journey 套件、外部监控。一个让所有本地门禁保持绿色的重命名,可能在几小时后于别人的会话里悄然破坏它们。

  • 当变更重命名可见文案或重构表面时,全仓库 grep 旧字符串/选择器——明确包含 test-harness 和 e2e 包——并在同一轮更新每个锚点。产生重命名的 diff 就是必须清扫的 diff
  • 评审测试:从 diff 里挑一个被重命名的字符串 grep 全仓库。diff 之外的任何存活命中,都是下一次 live 运行前的隐患
  • 结构优于文案:journey 需要锚点时,优先在表面拥有一个data-*属性,而不是显示文本——这样产品文案可以自由改动而不碰测试。当 journey 锚定文案而结构属性已存在时,标记它

二十三、让代码比你发现它时更好——整洁的 diff 不值一个不整洁的仓库(原则 26)

这是一条元原则,决定了评审的收尾姿态:

  • 绝不为了保持 diff 聚焦而回退顺手的改进。如果格式化器、linter 或 codemod 顺带清理了你的变更未触及的文件,也要提交(噪音大就单独提交)。回退它是在优化评审时的阅读体验,代价是每个未来的 pass 都要重复付出
  • 发现死东西就在这一轮删掉:死列、死参数、死函数、死导出、只有测试在调用的测试——连同为它辩护的注释一起删除。不要记笔记;笔记只是拖延,下一位读者还得重新推导它是死的
  • 发现的错误注释是缺陷,就地修正
  • 修复你的变更暴露出的潜在 bug:让很少跑的路径每次跑的工作,会暴露排序 bug、不可达的清理、从未触发的断言——那现在是你的 bug,因为它因你而变得可达
  • “改进”之前先验证:确认东西真的死了、错了、坏了再删或重写——grep 消费者、跑测试。自信地删除承重之物远比你在修的脏乱更糟
  • 边界:不要把无关的行为变更混进 feature 提交;不要因为你讨厌邻居模块的形状就重写它。这条规则覆盖机械整洁、死代码、错误注释、你使其可达的 bug——不是机会主义重设计
  • 评审测试:这个变更落地后,仓库里是否有任何文件比之前更糟,或携带已知的错误陈述?如果有,这一轮就没做完

二十四、技能协同:在 jevgrep 仓库中的完整交付闭环

code-review不是孤立运行的。jevgrep 仓库把代码评审、重构、测试、文档写作组织成一个可编排的技能链:

技能路径负责的关口
refactor-clean.agents/skills/refactor-clean/SKILL.md形状(shape):让每个概念只有一个清晰的家
code-review.agents/skills/code-review/SKILL.mddiff:审计已定型的变更
write-docs.agents/skills/write-docs/SKILL.md文档:更新变更触及的文档并验证链接链
write-tests.agents/skills/write-tests/SKILL.md测试:钉住真实行为而非实现细节
review.agents/skills/review/SKILL.md编排:顺序、循环与唯一结论

review技能规定:形状先于 diff 先于文档——重构便宜时先做(refactor-clean),审计已定型的形状(code-review),结构问题会把流程送回第二步而不是继续前进,最后更新文档并追踪从根 README 向下的链接链。三个关口全部 clean 或已解决才算 done。

而code-review的原则 9、12 与write-tests技能高度共振——后者的“断言可观察行为而非内部函数”“绝不断言编译器已保证的类型”“断言真实值而非集合大小”几乎就是评审原则的测试侧镜像。两条技能可以互为检查清单。


二十五、在 jevgrep CLI 中的落地证据

本文提到的原则在 jevgrep 自身代码中均有迹可循,可作为评审技能的活教材:

原则 12(驱动最外层入口点)与原则 9(断言真实值)——apps/cli/test/args.test.ts 通过parseCommand(CLI 的公开参数入口)传入用户会键入的原始参数,断言完整的解析结果对象,包括:

expect(parseCommand(["find behavior", "--hidden", "--no-cache", "--max-source-bytes", "12", "--", "-tree"])).toEqual({ kind: "search", query: "find behavior", root: "-tree", // 连字符开头的 root 通过 -- 分隔 noCache: true, maxSourceBytes: 12, policy: { hidden: true }, });

并对非法输入断言抛错的具体信息("Unknown option"、"positive integer"),而非只检查“抛了错”。

原则 5(安装/运行分离)与原则 10(无薄封装)——apps/cli/src/skill.ts 中installSkill仅做一件事:组装npx skills add dzhng/jevgrep --skill jevgrep参数并派生子进程,把安装委托给 skills 安装器;运行时搜索逻辑(apps/cli/src/args.ts)完全不触碰安装细节。

原则 7(收紧保证)——apps/cli/src/args.ts 对--concurrency与--max-source-bytes在解析层就完成全部校验(正整数、非负安全整数、0表示无限),下游无需再防御非法值;auth、doctor、skill、cache clear各命令的参数约束也在同一入口严格收窄(如auth只在--stdin且--provider合法时接受 provider)。

原则 21(内部 API 无版本机制)——CLI 帮助文本(同文件help常量)明确“Saved credentials only; provider key/URL environment variables are ignored”,认证状态只有一种真实来源,不保留环境变量等平行通道。

技能的实际使用方式则记录在 skills/jevgrep/SKILL.md(及仓库根 .agents/skills/jevgrep/SKILL.md):jg检索输出以 “summary + ranked file list → verbatim source excerpts → detailed locations” 的结构呈现,End context.标记完整上下文结束——这些输出正是code-review技能评审跨文件变更时“grep 旧引用、追踪消费者”所需的第一手材料。


二十六、结语:把 26 条原则当作一张可执行的评审 checklist

code-review技能的 26 条原则可以被归纳为四类主题,评审时按此顺序过一遍即可覆盖全貌:

  1. 真实性(1–4、26):名字、引用、注释、代码本身都必须反映当前现实,历史留在 git 里
  2. 边界与所有权(5、6、10、11、17、20、21、22、23):每个概念一个家,不重声明、不薄包装、不预置兼容机制、不过早抽取
  3. 测试与安全(9、12、14、15、16、25):驱动公共表面、断言真实值、身份来自认证、公共 API 最小化
  4. 数据与容错(18、19、24):索引处过滤、有界读取、批处理隔离单项失败

加上两条元纪律——原则 13(区分代码缺陷与工具链缺陷)与原则 7(绝不压制信号)——以及文档规定的输出协议(引用文件与行号、按类别分组、以 clean/not-clean 收尾),这套技能就可以作为任何编码 Agent 的提交前自动评审关卡,在 jevgrep 这类由 Agent 驱动迭代的仓库中,与review、refactor-clean、write-tests组成完整的交付闭环。

【免费下载链接】jevgrep

Find code by asking what it does. A CLI for coding agents that uses Jev to discover relevant files and source context.

项目地址:https://gitcode.com/gh_mirrors/je/jevgrep
点击查看免费下载

相关推荐

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

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

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

立即咨询