Files
eng-standards-main/docs/architecture/universal-ci-standard.md
T
姚章浩 ee28c0968f docs(architecture): 落库两份设计草案,并标注它们是过程记录而不是配置
两份草案此前只在本机工作副本里(未跟踪),而它们是这次改动的依据来源,
不留档就没法回头看"当初为什么这么定"。

同时在文头各加一行后续说明:已落地生效的部分已经并入 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 为准"。
2026-10-12 00:12:06 +08:00

13 KiB
Raw Blame History

通用工程规范修订草案: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/系统变更另行批准。