


在不削弱安全性的前提下,为 Go 服务器添加模块
为可扩展的 Go 服务器开发或审查功能时使用。让 AI 按从创建到清理的顺序编写每个模块,严格解析配置文件,在 Linux、macOS 和 Windows 上通过测试、代码检查和构建后再合并,并把拉取请求留给人来处理。
要使用这个AI规则
## 守住安全的默认设置,并决定新功能放在哪一层
对于面向互联网的服务器平台,应将安全默认值视为首要产品要求。
应将功能设计为可组合模块,而不是使其与核心紧密耦合。
应优先采用服务于一类用例的通用扩展,而不是仅针对一次部署的补丁。
确定一项更改属于顶层应用程序、可复用模块、配置适配还是命令行入口点。
为模块标识符保留命名空间,以免独立开发的组件发生冲突。
即使提供了便于人类使用的适配器,也要保留原生结构化配置模型。
对请求处理、传输安全、身份、证书管理和信任边界进行更严格的审查。
当所有权分散时,应跨相关存储库或软件包追踪安全敏感行为。
在理解安全关键更改所影响的信任边界和故障模式之前,不得将其视为可合并。
明确维护标准模块注册表,使随附组件可被发现和审计。
确保命令二进制文件导入预期的模块集合,而不是依赖偶然注册。
当一项新功能可以合理地位于多个层次时,应记录其架构位置。
拒绝仅为减少实现工作量而削弱安全默认值的设计。
从第一次设计决策起就要考虑与各受支持操作系统的兼容性。
## 按 Go 的常见写法处理错误、命名和注释
遇到错误时尽早返回,并将成功路径保持在最低缩进层级。
已有返回操作的分支之后不要再使用 else 分支。
URL、HTTP 和 ID 等常见首字母缩略词应按惯例全部使用大写形式。
选择能持续反映接收器类型的简短接收器名称。
错误字符串以小写文本开头,末尾不加标点。
导出的文档应写成以声明名称开头的完整句子。
当已分配的空切片没有语义价值时,应使用 nil 切片。
对预期的失败返回错误,而不是触发 panic。
在可能失败的操作附近处理错误。
只有在附加上下文有助于定位失败操作时才包装错误。
需要以编程方式处理时,应以调用方可以检查的形式保留错误。
避免使用会掩盖资源所有权或清理过程的巧妙控制流。
审查前运行格式化和静态分析。
即使存在另一种有效的 Go 风格,也要采用存储库已经确立的约定。
对于预期满足框架接口的类型,使用编译时接口断言。
除非有意进行的兼容性更改获得批准,否则应保持接收器名、包名和导出名称稳定。
## 按从创建到清理的顺序编写每个模块
通过框架的标准注册机制注册每个模块。
返回包含命名空间模块 ID 以及新实例构造函数的元数据。
构造函数不得产生特定于环境的副作用。
将生命周期视为有序阶段:
1. 构造一个新值。
2. 将配置解码到该值中。
3. 配置运行时依赖项。
4. 验证完整配置。
5. 提供服务或执行模块功能。
6. 清理其拥有的资源。
在配置和预配数据可用之前,不得执行最终验证。
如果框架可能以这种方式调用清理操作,则要确保清理在部分预配之后以及反复收到关闭信号时仍然安全。
对预配、验证、配置解析和其他可选接口使用编译时防护。
将各项生命周期职责分开,以便区分配置错误和运行时故障。
从预配和验证过程返回可据以采取行动的错误。
不得将初始化失败隐藏在只能部分使用的模块之后。
只有真正拥有启动和停止行为的组件才能使用顶层应用程序接口。
配置、适配器和外部集成可能依赖模块 ID,因此应保持其稳定。
## 严格解析配置文件,并保护管理端点
通过框架的令牌分配器或等效的结构化迭代器解析面向用户的配置。
先读取指令名称,再读取行内参数。
将行内参数与嵌套块分开处理。
记录当前嵌套层级,并在解析器离开该块时停止。
明确识别受支持的子指令。
立即验证必需参数,并返回解析器的标准参数错误。
用包含意外值的错误拒绝未知子指令。
在解析器旁记录所接受的语法,将其作为持续维护的契约。
使适配器的输出与原生结构化配置模型保持一致。
在预配期间,通过框架上下文获取日志记录器和其他模块。
使用模块作用域的结构化日志记录器并附加字段,而不是构建非结构化消息。
不得将请求上下文或预配上下文存储在长寿命结构体中。
添加管理端点时,应实现框架的路由接口。
应用管理界面所要求的身份验证、授权和暴露规则。
在模块开始处理流量之前验证配置。
## 少加新依赖项,守住包的边界
除非新依赖项的价值明显超过维护、安全和供应链成本,否则应避免添加。
如果一个很小的依赖项会带来不成比例的风险,应将小型且稳定的功能内联。
不得通过项目的公共 API 暴露外部软件包的类型。
将第三方行为封装在项目自有的接口和类型之后。
使用该语言的模块工具,使依赖项声明和校验和保持一致。
运行依赖项整理命令并审查其 diff,而不是接受无关的改动。
将配置适配器与运行时模块分开。
将测试实用程序与生产入口点分开。
将标准模块放入随附命令所使用的注册表。
未经明确的产品决策,不得将可选模块导入默认二进制文件。
保留协议处理、传输安全和证书操作周围的软件包边界。
只有在识别出抽象所服务的重复行为之后,才能选择通用抽象。
拒绝会掩盖简单实现的推测性抽象。
重构时,应保留可观察行为,或者记录并测试每一项有意更改。
对安全关键软件包和依赖项更改的审查应比常规内部代码更深入。
## 合并前通过全部测试、代码检查和构建
将每个必需的质量门禁视为阻塞条件,而不是建议。
启用竞态检测并运行完整的短测试套件。
为完整存储库预留足够时间,运行已配置的代码检查工具。
构建所有软件包,以发现缺失的接口、平台约束和注册错误。
对于性能更改,运行包含内存测量的基准测试。
将基准测试结果与适当的基线比较,并考虑结果波动。
针对受影响的服务器行为运行聚焦的集成测试。
如果 CI 支持 Linux、macOS 和 Windows,应确保测试在这些平台上均能通过。
即使其他位置存在无关警告,也要检查已更改文件中的警告。
只要任何必需的测试、代码检查、构建或基准测试门禁缺失,就不得将拉取请求标记为可合并。
记录命令和相关结果,使审查者可以复现这些证据。
在更改生产代码之前,应区分测试失败与环境失败。
验证范围应与更改相称,同时仍覆盖每个直接受影响的门禁。
针对审查意见进行任何代码更改后,应重新运行受影响的门禁。
将竞态报告和不稳定的并发失败视为需要调查的缺陷。
## 编写表驱动的单元测试和使用独立端口的服务器测试
当多个输入具有相同行为时,优先使用表驱动测试。
为每个用例指定明确的输入、预期输出和预期错误状态。
既要检查预期错误缺失的情况,也要检查返回意外错误的情况。
适当处理错误条件之后才能比较返回值。
包含有效、无效、边界和回归用例。
如果仅靠索引难以诊断故障,应为用例命名。
保持测试夹具精简且具有确定性。
使用项目的服务器测试工具集测试端到端配置行为。
用隔离的配置和明确的格式初始化测试服务器。
使用非标准端口,以免与本地运行的服务冲突。
必要时为管理、明文流量和加密流量分别预留端口。
断言状态、正文和其他可从外部观察到的行为。
清理测试创建的服务器、侦听器、文件和 goroutine。
不得依赖测试顺序或共享的可变全局状态。
既要测试配置解析错误,也要测试服务器成功启动。
当路径、套接字、信号或进程行为不同时,添加平台特定用例。
集成测试的范围应足够集中,以便通过失败定位遭到破坏的契约。
## 把拉取请求、安全报告和协议签署留给人来做
将议题讨论、拉取请求、许可协议和安全报告视为由人类治理的外部操作。
AI 助手不得冒充人类贡献者,也不得代表他人接受法律协议。
除非治理政策明确授权该代理执行相关操作,否则不得创建或提交外部议题、拉取请求或安全报告。
将审查协助限制在允许的角色内,并在需要时说明 AI 的参与。
如果贡献政策要求披露,不得隐瞒 AI 的参与。
要求人类操作者理解并能够解释提交的每一行内容。
在可行时用自动检查测试 AI 辅助代码,否则进行全面的人工检查。
审查生成的代码中是否存在复制的材料、不兼容的许可和未经验证的主张。
不得编造漏洞细节,也不得提交未经验证的安全报告。
翻译或编辑协助必须保留人类作者已经验证的安全事实。
仅限人类完成的签名、证明和贡献者协议应交由责任人处理。
当请求的操作与贡献政策冲突时,应停止该操作并解释治理边界。
不得添加欺骗性文件、注释或提交,以此替代被禁止的外部操作。
在不绕过社区流程的前提下保持补丁的技术价值。
批准前,将披露、理解、测试和许可分别作为独立门禁进行验证。
即使代理完成了大部分实现,人类仍须承担责任。
