两份草案此前只在本机工作副本里(未跟踪),而它们是这次改动的依据来源, 不留档就没法回头看"当初为什么这么定"。 同时在文头各加一行后续说明:已落地生效的部分已经并入 01 正本 (§3.1 测试语义、§4.1 CI/CD 分离、§4.8 必需检查清单与结果口径、§8 占位不许假报成功) 与 templates/;试点那份标注"已实施",并指向 knowledge-governance 的 scripts/ci_checks.py 与 .gitea/workflows/build.yml。 为什么必须标清楚:草案里写着"当前仅文档设计、不修改工作流", 而现在已经改了 —— 一份自称"尚未生效"的文档会让人以为规则还没落地。 验证:README 的交付物表已列上 docs/architecture/ 并写明"规则以 01 为准"。
13 KiB
通用工程规范修订草案:Git、代码质量与 CI
状态:架构文档草案(过程记录),供修订正本和实现模板使用;尚未替代根目录 01/02 正本,尚未推送。本文不是已运行的 CI 配置。
后续:本文中已落地生效的部分已并入 01-规范-Git与CI-CD(Gitea版).md(§3.1 测试语义、§4.1 CI/CD 分离、§4.8 必需检查清单与结果口径、§8 占位不许假报成功)与 templates/。看"现在是什么规则"请读 01;本文只解释"当初为什么这么定"。
1. 背景和目标
为所有项目提供一致的质量流程、检查契约和结果口径,以知识治理平台为首个验证样板。通用的是标准与流程,不强行统一语言工具和业务测试。CI 与 CD 分离。
用户已确认:main 是唯一长期分支。日常直接在 main 开发;需要审批或尝试新方案时才使用临时分支与 PR,测试通过且批准后合并 main,关闭 PR、删除临时分支,保留记录。
2. 约束条件
- 不引入长期 develop/release/feature 分支,不默认强制所有改动走 PR,不自动更改分支保护。
- 首期仅 CI:检查、测试、构建、证据;不部署服务、不迁移数据库、不访问生产数据。
- 当前仅文档设计,不修改工作流/生成器/业务代码,不启动 coder、tester 或 cicd。
- GPT 负责方案与实际 diff 审查,DeepSeek 负责另行批准的实现与修复;prototype 只承担 UI 原型与重大交互改版。
- push、合并、发布、sudo、Runner 配置更改仍需对应授权,分支策略不是远端写权限的授权。
3. 系统边界
通用规范负责 MUST/SHOULD、触发策略、检查与报告契约;语言模板负责工具选择;项目负责显式模块和验收清单;CI 引擎负责运行与提交状态;通知/预览是可选旁路。项目 CD 仅引用 CI 产物证据,部署细节独立管理。
推荐:一套通用规则 + Go/Python/Web 技术栈模板 + 显式项目清单。 备选:初期用一个 CI 作业串行执行,保持报告完整。 不推荐:依靠语言自动猜测决定必需项、模板默认携带部署、多个 Agent 自动审批合并。
4. 模块划分与规范条款
4.1 Git 与交付流程
日常:main 修改 → 本地门禁 → 提交推送(获得相应授权)→ 远端 CI 复验 → GPT 按需审查。 试验:临时分支 → PR → 头提交检查通过 → 用户批准 → 合并 → 读回合并结果 → 删除临时分支。
CI 在推送后执行,不能阻止已经接受的直推;main CI 红时优先修复或经批准使用 revert 回退,不重写历史、不推进发布。多 Agent 不并行写同一工作区。
保留 Conventional Commits:中文标题、≤72 字符、描述≥3 字符、冒号后一个空格、末尾无句号;scope 使用真实模块名;破坏性变更有 BREAKING CHANGE 说明。自动 merge/revert 等例外必须明确,不能用任意前缀逃逸。正文记录原因、取舍、真实验证及未验证项。
PR 合并读回发生在合并后,不是合并前:确认 state=closed、merged=true、merge_commit_sha 存在,再确认临时分支清理。不能因为接口空响应而重复合并。
4.2 通用代码质量
- 按职责组织模块,不同义复制,不为尚未出现的需求过度抽象。
- 统一格式与命名;注释优先解释原因,允许必要的接口/字段语义说明。
- 不吞错误;对外错误稳定且不暴露内部秘密,内部诊断保留可定位信息。
- 外部请求定义超时;重试需考虑幂等和次数限制。
- 输入校验与权限检查在可信边界执行;不信任客户端身份字段。
- 日志不包含密钥、原始凭据或不必要的个人/业务敏感内容。
- 新功能覆盖正常和异常路径;缺陷修复补回归测试;禁止通过删除测试/降低规则来获得绿灯。
- 行为变更同步接口与文档;Agent 不擅自改变契约、技术栈或扩大范围。
格式、静态检查、测试与构建自动验证;设计合理性、权限语义和行为保持由审查与业务验收补充,不能假称全部可由 Lint 判断。
4.3 通用 CI 检查顺序
| ID | 必需检查 | 判据 |
|---|---|---|
| identity | 触发提交/检出身份 | 实际 HEAD 等于事件完整 SHA,版本工具存在 |
| commits | 本次提交信息 | 范围准确、非空且规则通过;手动重跑按已记录事件语义处理 |
| dependencies | 锁定依赖安装 | 锁文件存在、受控版本、依赖清单不被静默改写 |
| format | 格式 | 不符合规则非零退出;CI 不自动修复 |
| static | 静态检查/类型/Lint | 明确的语言模块检查全部通过 |
| tests | 自动化测试 | 必需套件实际执行且通过,无测试不能假绿 |
| build | 构建 | 声明的模块构建成功 |
| contracts | 项目契约 | 版本与产物/接口等声明契约通过 |
| security | 密钥/依赖漏洞 | 无泄漏,无未获授权的适用高危/严重风险,工具运行成功 |
依赖安装后串行、失败即停;汇总始终执行。测试依赖产物时,在其测试前完成相应构建,记录依赖关系;Go test 会构建测试程序、Vitest 通常测源码,不要求所有单测必须先运行单独构建。
项目必须声明各技术栈的适用检查,不适用项在清单里说明理由,不能执行时临时静默跳过。无可运行检查的项目不得直接报告成功。文档类仓库可声明链接/结构/模板契约检查,不强行要求业务单测。
4.4 统一入口与依赖
每个项目只定义一个权威本地门禁入口,名称可为 make verify、make check 或语言脚本,但 AGENTS、Runbook、CI 必须引用实际同一入口,不独立复制第二套核心步骤。
提交信息范围、检出、安全扫描可以是外围门禁,但清单必须明确。严格串行不能只依赖 make 默认行为;调用者传入 -j 时也不得产生互相覆盖产物的并发。
依赖必须按锁文件安装;缺失锁文件不能退化成无约束 install。缓存只加速,不作为通过证据;不得隐式依赖上次构建残留。工具缺失直接失败,不在运行中静默升级。新工具初次安装/Runner 预置需要另行授权。
4.5 测试范围与安全门禁
必需测试在隔离环境执行。依赖数据库的集成测试使用可销毁测试库,不连接生产,不触发真实扫描或发布。环境不足时标为未验证并说明补验路径;不能声称全部验收完成。
覆盖率先建立证据基线,不立即设任意百分比硬门槛。必要场景包括权限拒绝、输入非法、任务重试/幂等、关键状态转换,具体由项目定义。
密钥泄漏阻断,输出文件位置和类别而非秘密值;扫描范围覆盖本次变更及检出树,存量历史审计单独安排。适用高危/严重依赖漏洞阻断;无法确认适用性的结果必须显式待审查。例外记录漏洞ID、影响范围、理由、责任人、批准记录、截止条件/日期,过期自动失效。扫描工具或漏洞库获取失败不能伪装无漏洞;不得发送项目源码给未授权外部服务。
4.6 通知、预览与触发
推送 main 和临时分支触发同一质量检查;可提供人工重跑,不默认 tag 部署,不叠加相同 push/PR 重复运行。
报告绑定完整 SHA 和 run_id;缺必需上下文不能使用 combined=success 放行。试验 PR 仍需要用户批准,不自动合并。
通知不阻断已完成的质量检查,通知失败单独标注;汇总本身故障导致无法确定质量时不能报绿。预览仅在所有必需检查成功后运行;预览不能写入运行中服务或生产目录,且不影响发布开关。跨作业结果显式传递,禁止假定 /tmp 共享。取消的旧运行不算失败已修复,也不算成功。
5. 数据模型草案
项目清单:modules、toolchain_versions、verify_entrypoint、required_checks、optional_checks、test_dependencies、version_source、template_revision。 检查报告:repository、commit_sha、run_id、event、policy_revision、checks[]、overall_status、artifact_refs、notification_status。 每个 check:id、required、command、status、exit_code、log_ref、reason。 状态:success/failure/skipped/cancelled/not_run/unknown。 overall_status 仅当身份核对通过且所有必需项 success 时为 success;其他情况如实失败/取消/未完成,不能默认为成功。 无业务数据库变更。
6. API 草案
不新增项目业务 API。项目以 CLI 入口产生退出码和结构化报告,CI 写回 Gitea。 已有 bridge 报告接口若启用,接收上述检查报告或兼容字段;通知协议迁移必须实测兼容,不盲改 bridge。 产物元数据至少含完整 commit_sha、工具链/模板版本、文件摘要,给后续项目 CD 使用。摘要由工具计算,不手填。
7. 权限、安全、日志
不向待测代码全局提供生产、发布或通知密钥;敏感值仅在需要的可信步骤可用。凭据不放 remote URL、argv 或日志。外部输入经环境变量/数据参数读取,不直接插入 shell 源码。
CI 脚本/工作流本身属于审查对象;CI 通过不是授权。模板不得自动 sudo、推送、合并或更改保护。日志可定位首个失败步骤,脱敏且给出复现入口。
8. 部署与 CI/CD 影响
通用 CI 默认不生成 deploy:test/deploy-production。CD 各项目独立设计部署目标、产物形式、迁移、健康检查与回滚。通用规范仅保留人工授权、凭据安全、可追溯、使用验收过的同一产物和失败恢复原则,不强制 Docker、指定云、端口或数据库。
未实现占位不得输出“已部署/已送达”并返回成功。生产部署触发及批准方式由项目设计,不能与默认 main CI 隐式绑定。
9. 风险与迁移
存量格式与 Lint 问题应独立清理,避免混入业务修改;批准的技术债基线需列明,不能永久忽略全目录。新工具可达性、工具链版本与测试环境需实测,不修改 Runner 来掩盖应用问题。
现有正本中服务器地址、Docker-only、DobotAI 数据库/迁移等内容迁至环境/项目附录,保留原有操作记录但标明不是跨项目强制规范。
必须同步正本、Runbook、接入文档、模板和生成器,避免新旧规则并存;本草案未落入模板前不得声称规范已全部生效。
10. Gitea Issue 草案与开发拆分建议
[ARCH] 统一通用规范与 CI-only 边界
范围:01 正本、02 Runbook、06 接入文档、README 与 templates/README。 验收:单 main 与短命 PR 口径一致;日常路径不强制 PR;CI 与 CD 分离;测试语义正确;合并读回顺序正确;项目环境信息不再成为通用强制条款。
[ARCH] 定义技术栈检查与统一入口契约
范围:检查清单、工具版本来源、Go/Python/Web 模板要求。 验收:每项有实际工具选择、输入范围、通过/失败判据、适用理由与正反例;本地与 CI 同源;依赖解析不能静默漂移;严格串行不受 make -j 干扰。
[ARCH] 定义报告汇总、预览与接入安全契约
范围:事件 SHA、检查状态、通知/预览、接入器合并权限。 验收:版本失败不通知成功/不预览;缺失/超时/取消不假绿;跨作业无隐式文件共享;未获批准不请求合并;占位部署无假成功。
实现拆分建议:先文档同步,再核心门禁,再报告/检出,再模板/生成器,再试点负例验证。由另行批准的 DeepSeek 实现,GPT 审查实际 diff 与执行结果;当前不创建 DEV 任务。
必须通过的通用反向验收
| 场景 | 预期 |
|---|---|
| 合规干净检出 | 所有必需项成功,SHA 对应准确 |
| 格式错误 | format 失败,不自动修复 |
| 静态/类型错误 | static 失败,后续标未运行 |
| 故意失败的单测 | tests 失败,不能由构建成功覆盖 |
| 必需测试不存在或必需套件跳过 | 不得报告全绿 |
| 构建失败或版本契约失败 | 不预览、不通知质量成功 |
| 依赖锁缺失/不一致 | dependencies 失败 |
| 无真实秘密的合成密钥扫描夹具 | 扫描器按指定检测规则阻断,不打印值 |
| 必需工具/漏洞库不可用 | 显式失败/未完成,不声称安全 |
| 事件 SHA 与检出不一致 | identity 失败 |
| 通知服务不可达 | 质量结果不变,通知失败另列 |
| 接入器读到失败/未知/超时状态 | 不请求合并 |
不得用故意失败提交污染日常 main。优先隔离夹具测试,必要时使用经用户同意的短命试验分支;验收后删除分支、保留运行记录。
11. 需要用户确认的问题
分支策略和 CI/CD 分离已确认,不重复提问。待实现前确认:技术栈工具的准确版本、存量格式清理范围、安全例外、临时集成环境、远端推送授权。任何 Runner/系统变更另行批准。