


为可扩展的Go服务添加功能,并编写在配置覆盖下也能通过的测试
修改会被下游构建改名或定制的Go服务时使用。在日志中保留追踪上下文,把新工具注册到合适的组,在配置被覆盖时测试公开行为,并更新生成的文档。
要使用这个AI规则
## 编辑前先找出负责此修改的包
修改代码前,先对变更进行分类并找到事实来源。
- 识别命令入口点、领域包、配置层、传输与授权层、协议实现、输出层、能力注册表以及版本元数据。
- 将业务逻辑保留在其所属的源代码包中,而不是放入命令接线或分发包装器。
- 将语言包和安装程序目录视为轻量的二进制分发适配器;仅在处理打包或版本工作时修改它们。
- 阅读管理受影响区域的构建定义、测试配置、邻近实现以及面向用户的文档。
- 编辑前区分人工编写的源文件、生成文件和构建产物。
- 列出所有受影响的处理程序、公共类型、注册点、配置路径、测试、文档和包表面。
沿用仓库既有的布局和命名约定,不要引入一套平行结构。
## 通过带上下文的日志包装器记录日志,保持与追踪的关联
生产代码输出日志时,使用仓库的上下文化日志包装器。
- 将请求上下文传递到实际记录日志的位置;如果调用链尚未携带上下文,则添加上下文参数。
- 当包装器会为记录补充遥测关联信息时,不要直接调用框架的基础上下文日志记录器。
- 如果函数启动了新的追踪 span,请在 span 启动后重新获取上下文化日志记录器;先前捕获的日志记录器仍保留旧的 span 上下文。
- 将结构化值附加到活动上下文,使日志桥接层能够把日志与正确的追踪关联起来。
- 检查并处理生产代码返回的每个错误,不要将其丢弃。
- 添加诊断信息时,保留仓库既有的脱敏、授权和可观测性边界。
通过可观察结果验证关联和错误行为,不要只依赖日志语句是否存在。
## 按处理函数、分组、注册的顺序添加新工具
实现新能力前先完成设计:确认其名称、分组、输入 schema、行为和评估覆盖范围。
1. 实现负责该能力逻辑的处理程序。
2. 定义其公共工具或命令契约,并将其连接到处理程序。
3. 将其添加到适当的能力组;如果没有合适的组,则创建一个职责明确的组。
4. 通过仓库的初始化路径注册新组。
5. 同步更新行为测试、配置参考、生成目录和用户文档。
每个能力组都应位于各自所属的目录中。避免重复的注册路径,也不要使用会暴露内部实现细节的名称。
## 使用声明好的构建目标,未经要求不部署
使用仓库声明的构建目标,不要凭记忆重新拼装命令。
- 运行前先了解哪个构建目标会格式化源代码、整理模块、编译单个平台,或构建所有受支持的平台。
- 检查生成的 diff,因为构建目标可能会按设计重写依赖元数据或生成文件。
- 引入模块后保持依赖声明整洁,并运行仓库固定版本的静态分析目标。
- 保留受支持的本地和远程执行模式,包括显式标志、环境变量、默认文件和集群内配置之间已有文档说明的优先顺序。
- 记录首次使用时会下载工具或环境的测试或 lint 目标;缺少网络访问可能导致的是设置失败,而不是代码失败。
- 保持包管理器包装器轻量,并使其与编译后的二进制文件同步,不要重复实现服务逻辑。
将会下载、发布、push 或部署的目标视为外部操作边界。先检查其契约;除非任务明确包含发布工作,否则绝不发布或部署。
## 测试公开行为和边界情况,而不是私有函数
把公共 API 当作黑盒来测试,并在可行时优先使用真实实现或集成测试。
- 按照仓库的测试套件约定组织测试,并为每个测试文件提供对应的套件。
- 使用嵌套子测试对相关场景进行分组,并为每个用例赋予描述行为的清晰名称。
- 理想情况下,每个用例只用一个聚焦的断言证明一种行为。
- 覆盖成功路径、回调、状态变化和可观察输出,同时避免让测试耦合到私有函数。
- 为 nil 或 null 值、空集合、无效索引、类型不匹配、格式错误的输入和错误路径添加边界用例。
- 对必须成功的设置操作使用前置断言,然后明确断言预期错误或值。
- 绝不要仅为了让测试更简洁而忽略错误。
修复缺陷时,先编写一个聚焦且会失败的测试;修复后运行受影响的包或套件,最后运行仓库要求的完整测试目标。
## 默认值和名称被覆盖时,配置测试仍能通过
当下游构建覆盖默认值、功能名称或已启用的能力集合时,配置测试仍必须有效。
- 普通测试套件从不含覆盖项的基础配置开始,然后在其上叠加测试专用设置。
- 对于简单配置,将解码后的值合并到套件的现有配置中,使测试工具已建立的运行时字段保持不变。
- 当某个部分存储延迟值或原始值时,使用所需的元数据感知两阶段读取器,以完整解析这些部分。
- 完整读取配置后,明确恢复仅用于运行时的字段,例如连接路径、输出选项和只读状态。
- 对于重新加载测试,要基于运行中服务采用的覆盖感知默认值有意构造候选配置,然后继承活动的运行时字段。
- 将所需能力追加到现有列表;绝不要用假定的上游默认值替换该列表。
- 动态解析可重命名的公共名称;但当解析器契约要求时,应保持解析器的字面注册键固定不变。
- 绝不要在断言中硬编码容易被覆盖的默认值、公共名称或功能集合。
只要配置变更跨越这些边界,就要同时测试基础行为和至少一条覆盖路径。
## 把共用测试辅助放在一处,区分准备失败和产品缺陷
将通用测试辅助工具放在仓库共享的内部测试区域,并通过清晰的用途、输入和示例为其编写文档。
- 保持辅助工具不依赖单一功能,使多个包都能复用。
- 优先采用真实的用户或协议交互,不要使用绕过生产行为的底层捷径。
- 明确列出测试前提,包括本地集群模拟器、已下载的环境、凭据或所需的网络访问。
- 在诊断信息中区分设置失败和产品失败。
- 在不使用低价值用例虚增指标的前提下,争取对公共 API 实现高覆盖率,尤其是边界条件和失败路径。
- 使测试配置、别名和生成的 fixture 与当前测试运行器保持一致。
存在下游定制时,应纳入针对能力重命名、默认值变更和配置重新加载的代表性测试。
## 通过生成工具更新文档,并让各发布包保持同一版本
更新受代码或配置变更影响的每一个权威表面。
- 如果仓库约定如此,新文档应使用小写文件名。
- 根据功能影响更新索引、配置参考、prompt、日志、可观测性、身份验证和集成指南。
- 将生成的表格和参考部分视为生成内容;保留其成对标记,并通过批准的生成器更新它们。
- 除非仓库策略明确要求,否则不要直接编辑生成部分,也不要提交构建产物。
- 使原生二进制文件、容器镜像和语言包包装器与同一版本的服务行为保持一致。
- 运行与变更相关且文档规定的构建、测试、lint、文档生成和聚焦打包检查。
提交变更前,确认最终 diff 只包含预期的源代码、测试、文档和包更新。仅当任务明确包含发布时才运行发布目标,并报告任何有意排除在范围外的更广泛检查。
