


为多模块仓库添加 provider 和 generator 插件
让AI在由 secret provider 与 generator 扩展的多模块仓库中工作时使用。所有工作都通过任务运行器执行,按既定方式添加扩展,并在推送或发布之前停下。
要使用这个AI规则
## 只通过项目的任务运行器执行构建和测试
本仓库通过单一的任务运行器对外暴露其构建、测试、lint 与打包命令。请先阅读该文件以了解可用的目标(target),并通过这些目标来执行全部工作。
不要直接调用底层的语言测试运行器、linter 或 chart 工具链。这些目标会设置构建标签(build tag)、模块范围、环境以及代码生成步骤,而直接调用会悄无声息地跳过它们。直接调用可能得到一个通过的结果,却与评审关卡实际产出的结果并不一致。
## 运行完整的评审目标,最后检查生成内容的差异
作为变更关卡的是那个单一的聚合评审目标,而不是它内部的各项单独检查。请运行聚合目标,而不要挑选你认为相关的那几项检查。
在全部内容提交之后,把生成物差异检查作为最后一步来运行。大量生成内容存在于主评审目标之外:打包 chart 的测试、渲染出的 manifest,以及文档。该检查之后工作区保持干净,才是这些内容全部被重新生成过的证明。这正是由 Agent 编写的变更最常出问题的环节,恰恰因为这一步感觉像是多余的。
## 修改源类型或模板,绝不手工编辑生成的文件
标记为生成物的文件归属于生成它们的生成器,而不是贡献者。绝不要手工编辑它们,哪怕只是改一个字符的修复也不行。
请修改它们所依据的源类型或模板,然后运行生成目标——聚合评审目标本身已经包含了它。手工编辑只能存活到下一次重新生成为止,之后要么毫无提示地消失,要么产生一份令人困惑、需要别人来理清的差异。
## manifest 从 chart 重新生成,快照用更新目标重新生成
打包 chart 是部署 manifest 的事实来源。提交在仓库中的静态 manifest 是由它生成的,因此应当修改 chart 并重新生成,而不是去编辑输出结果。
Schema 测试使用快照测试。修改 schema 类型之后,请运行快照更新目标并审阅由此产生的差异,而不要直接编辑快照文件。把出乎意料的快照变化当作一个信号,去重新审视你的类型改动,而不要当作可以接受的噪音。
## 在提交备注中写下设计决策和取舍
为每一次非琐碎的提交附上一条 commit note,描述关键的设计决策、你权衡过的取舍,以及你踩到的坑。备注会一直附着在该提交上,事后仍可被查询,从而保留下仅凭差异无法承载的推理过程。
备注要写得客观而具体:你选择了什么、你否决了什么、以及为什么。只是把差异复述一遍的备注是浪费。
## 在合并前把不易察觉的模式写进共享指南
当你在实现过程中发现某个非显而易见的模式时,请在该变更合并之前把它加入共享的指南文档,而不要等到之后上下文已经消失时再写。
条目要写得足够通用,以便适用于整个代码库,而不是只适用于你恰好正在开发的那一个功能。只描述某一个扩展的模式,应该放进那个扩展自己的文档里。
## 每个扩展独立成模块,构建标签放在注册文件中
可选的扩展存放在以它命名的目录下、属于它自己的模块中,而扩展包本身不携带任何构建标签。构建标签应放在该扩展的中央注册文件里。
这种拆分使扩展包能够独立地编译和测试,同时由发布出去的二进制文件来决定链接进哪些扩展。请按字母顺序把模块 replace 条目添加到根模块文件中。构建过程会把所选的扩展集合作为构建标签传入,其默认值代表全部扩展。
## 把扩展的配置类型作为一行登记到共享的联合类型中
新扩展的配置类型放在共享 API 包内属于它自己的文件里。注册方式是在判别式联合结构体中添加一行槽位,其字段的序列化标签就是扩展名称。解析是依据已序列化联合体的第一个键来进行的,因此该标签必须准确且唯一。
把认证信息嵌套在专用的 auth 结构体之下。当提供多种认证方式时,请把该结构体约束为最多只有一个属性,这样含糊不清的配置会在准入(admission)阶段就被拒绝,而不是等到运行时。只要后端使用 TLS,就要包含证书 bundle 字段和证书 provider 字段。已冻结的 API 版本仍然接受全新的扩展槽位;被封闭的是那些已有的字段。
## 用共享辅助函数读取凭据,不跨越命名空间
凭据解析、证书获取、selector 校验、元数据解析以及指标标签常量,全都有共享的辅助函数。请使用它们,并严格按照每个辅助函数的要求传入 store 类型(kind)和使用方资源的命名空间。
尤其是凭据解析器,它执行着把集群级 store 与命名空间级 store 区分开来的命名空间作用域规则。自己手写的查找会悄悄变成跨命名空间读取 secret,那是一次权限提升,而不是风格问题。没有 store 的扩展类型应传入空的 store 类型,因为命名空间作用域对它们并不适用。
## 实现 client 的全部方法,不支持的操作返回专用错误
client 接口必须被完整实现;只有 close 方法可以是空操作。
当某个 secret 不存在时,请返回专用的 not-found 哨兵错误,因为 reconciler 的删除策略依赖于区分"不存在"和"失败"。要如实声明能力,是只读、只写还是读写。只读的实现同样要实现写入和删除方法,但必须从中返回哨兵错误,绝不能返回 nil 错误——那会为一次根本没有发生的操作报告出一个无声的成功。在 JSON 载荷内部查找属性时,请使用约定的 JSON path 提取器。
## 只有在创建 client 很慢或代价高时才加缓存
默认不使用缓存。只有当 client 的构造确实代价昂贵时才加入缓存,例如令牌交换、租约获取或身份联合。
按 client 划分的缓存应以 store 的名称、命名空间和类型作为键,并以 store 对象的 resource version 作为版本,这样配置的修改就会自动使缓存条目失效。按 secret 划分的缓存应放在 client 内部,做成带过期时间且有容量上限的缓存,并且它的生存时间和最大容量必须是面向用户的配置项,而不是硬编码的常量。
## 让特性开关从 chart 的值一路贯通到初始化
一个特性开关会走一条固定的路径:先是打包 chart 的一个值,然后是 deployment 上的额外参数,然后是命令行标志,然后是标志注册,最后是初始化。
请在扩展包的初始化函数中注册标志,由根命令负责收集它们,并在 manager 启动之后再执行初始化,而不是在注册阶段执行。在进程外运行的依赖应当以 sidecar 子 chart 的形式发布,而不是链接进主二进制文件。如果某一类扩展此前没有使用特性开关的先例,请遵循既有的模式,但要预料到自己是第一个这么做的人,并在评审中说明这一点。
## 先运行脚手架命令,再补上它遗漏的部分
如果新扩展有可用的引导命令,请先运行它,并把文档中记录的手动步骤当作一份审计清单,用来核对它生成了什么、又遗漏了什么。
脚手架通常会接好 API 类型、模块文件、注册调用、判别式联合条目、kind 枚举值以及解析器的 switch 分支。它们通常不会接好访问控制规则、文档页面、示例片段、导航条目或打包。请逐项走查那些未被覆盖的清单,而不要想当然地认为脚手架已经把活干完了。
## 让 generator 保持无状态,清理可以安全地重复执行
generator 型的扩展会以原始 JSON blob 的形式接收其配置并自行反序列化,会在一次调用中返回所生成值的完整映射,而不是逐个键返回,并且会返回一个不透明的状态 blob,该 blob 在生成与清理之间被持久化保存。
默认保持无状态:不返回状态,并使用空操作的清理。只有当某个外部资源之后必须被释放时才返回状态。清理必须是幂等的,因为当生成之后状态持久化失败时,框架会把它作为回滚来调用,而在删除时又会通过 finalizer 再调用一次。
## 在中央注册文件中注册扩展,避免名称重复
扩展包会导出一小组固定的构造函数与元数据符号,注册则发生在一个中央文件中,由它把这些符号交给注册表。
注册在遇到重名时会 panic,所以请慎重选择标识符,并确认它尚未被使用。scheme 注册与行为注册是分开的,两者都必需:运行时解析器先通过 scheme 加载类型化对象,然后按 kind 分派到已注册的实现。当某个集群级的伞型类型需要从联合体 spec 中实体化出一个合成的命名空间级对象时,每一个扩展都必须在那段转换逻辑中拥有对应的分支。
## 为每个扩展写文档页面,并复用共享片段
为该扩展撰写一个文档页面,遵循约定的章节顺序:引言、认证或配置、使用方资源的 spec,以及可选的推送或写入流程。
把可运行的示例放在共享片段目录中并以嵌入(transclude)方式引入页面,而不要重复粘贴文本,这样一处修复就能传播到所有地方。共享的认证方案只在一个独立页面上记录一次,并从各服务的页面链接过去,而不要复制到每一页里。导航条目请追加在相关章节的末尾,因为这个顺序是按历史沿革而非按字母排列的。
## 只在本地工作,绝不推送或发布
Agent 可以检视仓库、解释代码、提出变更建议、编辑本地文件、编写测试、更新文档、运行检查,以及准备一份供人工评审的本地差异。
Agent 不得创建 pull request、推送分支、发布 release、上传软件包、修改仓库设置、变更权限、轮换凭据、修改 secret,也不得执行任何其他对外写入的操作。
如果被要求执行某个被禁止的操作,不要执行它。取而代之的是,创建一个本地文件,在其中记录被请求的操作、它被禁止的原因、已完成的本地工作(如果有的话),以及人类贡献者接下来应当采取的手动步骤。
## 宣布完成前,确认差异最小且测试已运行
在把工作呈报为已完成之前,请核实:意图已被记录在案;差异是最小且精准的,没有触及任何与本次工作无关的相邻注释或代码;相关测试是通过项目任务运行器运行的;文档也已更新。
如果验证中有任何部分未能完成,请明确说明并解释原因,而不要把一个只经过部分验证的变更当作已完成来呈报。
