


修改大型Python工作流单体仓库,而不把它改坏
在负责调度和运行工作流的大型Python单体仓库中让AI改代码时使用。守住调度器、工作器和数据库各自的分工,把依赖放进正确的软件包,先为改动的行为写测试,检查完整差异后再提交拉取请求。
要使用这个AI规则
## 修改前,先找到负责的软件包和它的说明
在文字说明中使用项目的规范领域术语。按照代码要求原样保留字面标识符、命令、路径、配置键和兼容性名称;不要仅为统一风格而改写它们。
编辑前:
- 确定负责的软件包、其本地指令,以及最近的架构或测试指南。
- 使用项目管理的开发和测试包装器,不要直接调用宿主工具。
- 通过已有文档说明的一次性设置安装仓库的钩子或命令兼容层。
- 临时辅助脚本只能放在指定的挂载开发区域,并在任务完成后移除。
- 根据实际变更的文件和软件包选择检查。
将生成的依赖锁定文件及类似产物视为官方生成器的输出,绝不能当作源码手工编辑。
## 不让调度器运行工作流代码,不让工作器直接访问数据库
更改编排代码之前,先理解数据流:
1. 作者通过公共SDK定义工作流。
2. 隔离的处理器解析这些定义并持久保存序列化的工作流数据。
3. 调度器读取序列化数据,不得执行作者提供的工作流代码。
4. 工作器通过受支持的SDK或API执行任务,不得直接访问元数据数据库。
5. API服务负责协调用户界面及客户端与持久状态之间的交互。
6. 事件触发服务与调度器和工作器分开运行。
组件之间使用短期且范围严格受限的凭据。用于阻止直接访问数据库的软件检查是有用的防护栏,但面对蓄意恶意代码时,并不构成安全边界。
提出修复方案之前,先对疑似安全问题进行分类:
- 可利用且违反已有文档说明之信任模型的行为属于漏洞。
- 已明确声明在信任模型范围之外的行为属于已知限制。
- 不能修复已违反保证、只提供更安全部署选择的建议属于加固指南。
保持这些类别相互独立,使严重程度和修复措施与实际风险匹配。
## 把依赖放进导入它的软件包
将单体仓库视为一组相关分发包,而不是一个不加区分的软件包。核心编排、公共SDK、提供方集成、命令行工具、部署模板、开发工具和脚本可能具有不同的发布周期与依赖规则。
对于共享库:
- 保持其API精简且独立。
- 为其提供独立的源码树、测试、配置和声明的依赖项。
- 使用仓库支持的工作区链接,不要复制代码。
- 测试库本身以及每一个直接受影响的使用方。
将依赖项放入实际导入它的分发包中。变更跨越软件包边界时,修改清单之前先验证导入方向和发布归属。
使用受支持的工作流程重新生成锁定文件,并检查产生的依赖差异是否包含无关改动。
## 编写清晰的Python代码,让每次改动保持小规模
在变更仍然很小时,对每个已修改的Python文件执行格式化和代码检查。让生产行为保持明确:
- 不要使用断言进行运行时验证或处理可恢复错误。
- 注释应解释约束或意图,而不是复述代码。
- 使用单调时钟测量持续时间。
- 除了已有文档说明的循环依赖、延迟加载或可选依赖情况,导入应保留在模块作用域。
- 保护仅供类型检查使用的高成本导入,避免它们影响运行时启动。
- 抛出范围最窄且有明确含义的异常;不要引入宽泛的全捕获基类异常。
- 只在传输边界将领域失败转换为协议专属响应。
- 用动作动词命名函数,并保留必需的许可证标头。
优先采用小型、易审查的变更,不要趁机重构。如果清理并非实现所需行为的必要条件,应将其留到单独的变更中。
## 分小批写入数据库,避免拖慢调度器
接收数据库会话的函数不应隐式提交事务。如果代码库采用相应惯例,应将会话设为仅限关键字参数,并由事务所有者决定何时提交或回滚。
避免在调度器或维护循环中进行不受限制的批量写入:
1. 按有索引的列筛选。
2. 处理有上限的批次。
3. 在各批次之间提交事务或释放事务。
4. 持续处理,直到没有符合条件的行。
这样可以限制锁定时间、内存增长和其他调度器工作的饥饿。确认默认数据库上的行为;当已变更查询依赖后端专属语义时,还要运行备用后端覆盖测试。
绝不能将破坏性清理命令视为常规故障排除。清理数据库、卷、缓存或用户数据之前,先解析准确目标并取得规定的批准。
## 先写会失败的测试,只在需要时扩大测试范围
先编写表达确切变更行为的测试,并确认没有实现时它会失败。然后进行能让测试通过的最小变更。
使用仓库首选的测试框架和辅助工具:
- 在测试树中复现源码布局。
- 使用受规范约束的模拟对象,使接口偏移能够明确失败。
- 使用受支持的配置覆盖和时间控制工具。
- 对有意义的输入和后端变体进行参数化。
- 准确标记数据库测试,并让非数据库测试独立于数据库设置。
- 断言结构化的事件名称和字段,不要依赖不稳定的渲染日志文本。
不要单独测试标准库或第三方依赖项。测试此代码负责的集成行为。
先运行有针对性的测试,然后运行受影响软件包的测试套件、静态类型检查和代码检查;只有依赖范围确实需要时,才运行更广泛的测试套件。
## 同时更新CI规则和文档,只为用户看得到的改动写发布说明
当选择性CI行为发生变化时,同时更新选择逻辑、对应测试和文档。只存在于代码中或只存在于文字说明中的规则都不完整。
只为实际交付该行为的分发包中的用户可见变更添加发布元数据。内部重构、仅测试工作、开发工具和非用户可见维护通常不需要发布说明。
使用项目生成器生成锁定文件、命令参考、模式定义和其他生成文档。审查生成的差异,但不要通过修改生成文件掩盖正本问题。
交接前,运行相关的格式化、代码检查、类型、测试、文档和选择性检查关卡。记录任何有意跳过的关卡,以及它不适用的具体原因。
## 检查完整差异,从派生仓库提交拉取请求
发布前审查完整的任务差异。确认架构边界、安全假设、测试、生成输出、发布元数据和本地指令彼此一致。
进行大范围跨软件包重构、添加宽泛依赖、改变破坏性迁移行为,或执行尚未授权的外部发布之前,应先询问。没有明确批准时,绝不能泄露秘密、绕过必需钩子、手工编辑生成文件或运行破坏性的版本控制命令。
执行任何远程操作之前:
- 检查已配置的远程仓库,确认哪个是规范仓库,哪个是贡献者的派生仓库。
- 不要直接推送到规范远程仓库或其受保护的默认分支。
- 远程仓库的角色不明确时,重命名或重写之前先询问。
- 搜索已有拉取请求,避免重复工作。
- 通过仓库接受的工作流程进行变基或以其他方式与当前目标分支同步。
使用祈使语气,以自然文字写出体现用户影响的标题。在正文中说明变更原因,按要求披露AI协助,并包含相关issue引用。除非用户已授权,或者相关人员已参与该讨论,否则不要将自己添加为共同作者,也不要标记个人。
如果完整修复已准备就绪,应优先提交拉取请求,而不要创建重复issue。如果变更只是规避方案、缓解措施或部分修复,应创建或链接跟踪issue,并在拉取请求和临时代码附近同时引用它。
