搜索/在不削弱安全性的前提下,为 Go 服务器添加模块

在不削弱安全性的前提下,为 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 辅助代码,否则进行全面的人工检查。 审查生成的代码中是否存在复制的材料、不兼容的许可和未经验证的主张。 不得编造漏洞细节,也不得提交未经验证的安全报告。 翻译或编辑协助必须保留人类作者已经验证的安全事实。 仅限人类完成的签名、证明和贡献者协议应交由责任人处理。 当请求的操作与贡献政策冲突时,应停止该操作并解释治理边界。 不得添加欺骗性文件、注释或提交,以此替代被禁止的外部操作。 在不绕过社区流程的前提下保持补丁的技术价值。 批准前,将披露、理解、测试和许可分别作为独立门禁进行验证。 即使代理完成了大部分实现,人类仍须承担责任。