Files
eng-standards-main/03-待配置事项.md
姚章浩 5b65ed9579 docs: 正本与 Runbook/接入文档口径同步(测试语义、CI-CD 分离、门禁唯一入口、必需检查清单)
按草案逐条落到正本,并把三处已知错误的口径改回:

① 测试语义:删掉"单测跑的是构建产物,不是源码"这条被过度推广的说法。
   只有"跑产物"的套件(端到端 / 契约 / 产物自检)才必须排在构建之后;
   go test 自己编译测试程序、pytest 直读源码、vitest 默认也跑源码。
   写错这条的代价是给每个套件加假依赖、拖慢门禁并制造假故障。T8 同步改。
② CI 与 CD 分离:触发表删掉"推默认分支 → 自动部署测试环境",作业划分表删掉 deploy:test 行,
   §4.6 标注为"项目自己的 CD、不属于通用 CI",速查表同步。
③ 门禁入口:统一为 make verify(名字可不同,但 AGENTS/Runbook/CI 必须指同一个),
   §3.1、§8 清单、§9 速查表一致。
④ 新增 §4.8「必需检查清单与结果口径」:10 项必需检查的判据表 + 三条结果口径
   (失败即停但汇总照做、not_run/skipped 不算过、汇总故障不能报绿),
   以及预览/通知作为旁路的规则。
⑤ 接入文档:修掉"直推也拦得住"这句错口径,并写明接入器不再自动合并、
   --merge-pr 会先核对状态;试点记录里那一步标注为"当时的自动合并行为已改"。
⑥ 03/04/05 里的同源表述一并同步(生成物 jobs 与假成功占位的判据)。

验证:本批 18 处精确替换在脚本里逐处断言"恰好命中 1 次"(DRY-RUN 先过一遍再应用);
替换后全仓 grep 复查,旧口径只在"说明它已被改掉"的上下文里出现。
2026-10-12 00:12:06 +08:00

14 KiB
Raw Permalink Blame History

待配置事项清单

每项:现状(已核实)→ 要做什么 → 为什么 → 怎么验证 → 谁来做。 优先级:P0 = 不做则规范形同虚设;P1 = 影响发布可靠性;P2 = 一致性/卫生。 现状全部来自本次实测(命令在括注里)。

⚠️ 本清单只讲"还差什么";"怎么让它以后默认生效"(三渠道 + 新工程 5 步)见 05-应用机制-让规范在以后所有工程生效.md —— 别把两份读串。


P0

1. 分支保护 —— 已定:默认不开(不需要动)

  • 决定:按原稿口径,main 不受保护,所有改动直接进 main(正本 §1.1 / §1.3)。
  • 现状:曾给 Weknora/knowledge-governance 开过一次(禁直推 + 强制 build / build (push)), 已关掉;7 个仓现在 GET /repos/{r}/branch_protections 全为 []。
  • 这条知识别丢:将来真需要"谁都不能直推"时,开保护前必须做 06-接入既有工程.md §2 的体检 —— 盲目勾"必须状态检查通过"会让 PR 永远等一个不会出现的检查。判据仍然有效,只是默认不用它。
  • 可逆:开/关都是一次 API 调用或网页点一下,不涉及数据。

2. knowledge-adapter-service 的工作流不在 main 上

  • 现状:main 的 .gitea/workflows/ 不存在;build.yml 只在 ci/setup 分支(GET .../contents/.gitea/workflows?ref=ci/setup → 200,ref=main → 404)。仓库已有 runner-weknora-ka-01。
  • 要做什么:把 .gitea/workflows/build.yml + .gitea/scripts/{ci_gate.py,ci_report.py} 合到 main;关掉/删掉 ci/setup 分支。
  • 为什么:现在推 main 不触发任何校验——这个仓库的 main 处于"裸奔"状态。
  • 怎么验证:GET /repos/Weknora/knowledge-adapter-service/contents/.gitea/workflows 在默认分支返回 build.yml;推一个提交,actions/tasks 出现新 run。
  • 谁来做:开发(走正常 PR);合并前用 attach_repo.sh 的模板拷贝逻辑。

3. 生产发布的"人工确认"落地方式二选一(需在实例上实测)

  • 现状:Gitea 没有 GitLab 的 when: manual + manual_confirmation;生产部署目前完全不经过 CI(DobotAI 是人工在生产机 clone + build)。
  • 要做什么:
    • 方案 A:确认 Gitea 1.26.2 的 Actions 是否支持 environment: 及其审批;支持就在生产 workflow 上用。
    • 方案 B(不依赖平台):生产 workflow 只 on.workflow_dispatch,必填 sha + confirm=deploy-production,最后一步"切镜像"由本人在生产机执行。
  • 为什么:规范 §5.2 的三层确认里,第二层(参数)与第三层(人)已可落地;第一层要不要平台能力必须先实测,不能假设。
  • 怎么验证:在非生产仓库建一个 environment: test-protect 的最小 workflow 试跑;或直接采用方案 B 并留一条演练记录。
  • 谁来做:本人确认 + 开发实现。

4. "同一份构建产物"的产物落地方式(本环境当前不满足)

  • 现状:DobotAI 的做法是在目标机上各自 build(测试机 build 一次、生产机再 clone 源码 build 一次)——两份二进制并不逐字节相同,违反 §5.1。
  • 要做什么:
    1. 构建移进 CI(仓库 Runner 上 docker build)或至少只在一台机器 build 一次;
    2. docker save 出 dist/<repo>-<sha12>.tar + 写 release-<sha12>.json(含 image_id / tar_sha256);
    3. 产物放到一个两个环境都取得到的托管点(见第 5 项);
    4. 测试与生产都 docker load 同一份 tar,并各自断言 image_id 相同。
  • 为什么:这是本次规范最核心的新增要求。"测试验收过"必须等于"生产跑的就是那份字节",否则验收结论对生产无效。
  • 怎么验证:测试机与生产机各跑 docker image inspect --format '{{.Id}}',两个值相同;且都 == 清单 image_id。
  • 谁来做:开发(改造构建 + 部署脚本);本人验收。

P1

5. 构建产物的托管点

  • 现状:ci-bridge 的 /api/ci/publish 是给静态网页预览(tar.gz 解包 + URL)用的,不适合放镜像 tar / 大文件;/srv/aiball/ci/previews/ 下面只有 3 个目录。DobotAI 的 tar 目前不在任何统一位置。
  • 要做什么:定一个产物目录(建议 /srv/aiball/ci/artifacts/<ns>/<repo>/<sha12>/,与 bridge 复用同机同 token,按 sha 分目录 + 保留 N 份),或走对象存储/OSS。
  • 为什么:§5.1 要求"生产取同一个 tar",就必须有一个两个环境都能取到、且可按 sha 寻址的地方。
  • 怎么验证:从测试机和生产机各 curl 一次同一个 tar_sha256 地址,都能下到且 sha256sum 与清单一致。
  • 谁来做:本人定位置 + 开发接。

6. 生产/测试的部署凭据尚不存在

  • 现状:只有 3 个 Weknora 仓库配了 CI_BRIDGE_URL(variable) / CI_BRIDGE_TOKEN(secret),没有任何部署凭据(GET /repos/{r}/actions/secrets)。DobotAI 的部署靠本人在生产机手动执行。
  • 要做什么:按命名后缀建变量/密钥(Gitea 无 environment scope,见规范 §7.1):
    • Variables:DEPLOY_TEST_HOST DEPLOY_TEST_PORT DEPLOY_TEST_USER DEPLOY_PROD_HOST DEPLOY_PROD_PORT DEPLOY_PROD_USER ARTIFACT_BASE_URL
    • Secrets:DEPLOY_TEST_SSH_KEY DEPLOY_PROD_SSH_KEY ARTIFACT_TOKEN
  • 为什么:CI 要有能力"传产物"到目标机;同时 Gitea 无 File 类型 secret,私钥内容整体存 secret、由脚本落盘 0600。
  • 怎么验证:GET /repos/{r}/actions/variables 与 /actions/secrets 列出全部名字(值不显示);在一个 dry-run workflow 里只在变量名 + ✓/✗ 层面校验(绝不回显值)。
  • 谁来做:本人在网页/用 attach_repo.sh 的接口写入;凭据环节必须由本人操作。

7. Weknora/Enterprise-Knowledge-Base 接入(含分支收敛)

  • 现状:7 条分支(main + release/graph-guard-v0.7.1-r1、release/server-running-v0.7.1、develop/enterprise-kb、chore/db-pool-tuning、feature/dingtalk-richtext-image、feature/dingtalk-image-only);无 workflow、无 Runner;语言 Go+Vue。
  • 要做什么:分支收敛(该合的合、该删的删)→ 跑规范 §8 的 10 步接入清单。
  • 为什么:长期分支 + release/* 正是规范 §1.1 的反模式;且它没有任何校验。
  • 怎么验证:GET /repos/{r}/branches 只剩 main + 短命分支;actions/tasks 有新 run。
  • 谁来做:开发 + 本人确认分支删除范围(删分支不可逆)。

8. Runner 覆盖盘点

  • 现状:Weknora 三仓各一个仓库级 Runner(kg/dp/ka);aiball 组织级 1 个(runner-software-01,覆盖 protocol-docs 与 software-pc);Weknora 组织级 0 个。
  • 要做什么:每个新接入仓库都要有归属该仓库的 Runner(否则 run 永远 queued)。用 deploy_repo_runner.sh 起。
  • 为什么:规范 §4.2 —— "run 一直 queued" 的头号原因是仓库没有自己的 Runner,而不是工作流写错。
  • 怎么验证:GET /repos/{r}/actions/runners 的 runners 非空且 status=online。
  • 谁来做:开发(bash /srv/aiball/runner/deploy_repo_runner.sh <owner/repo> <name>)。

9. aiball/software-pc 的 runner 依赖第三方 action

  • 现状:validate.yml 用 actions/checkout@v4 + actions/setup-node@v4,在 runner-software-01 上 run#1 = success(该 runner 能取 action);但 Weknora 三仓 runner 上刻意不用。
  • 要做什么:在 validate.yml 顶部加注释说明"本 runner 支持取 action";并补上 npm ci(现在用 npm install,不可重现)。
  • 为什么:规范 §4.3 要求"按 Runner 配置区分"且要写明理由,否则下一个人会照抄到不支持 uses: 的 runner 上。
  • 怎么验证:把 npm install 改成 npm ci 后重跑 run,仍 green。
  • 谁来做:开发。

10. 生产迁移与回滚脚本的"幂等门"复核

  • 现状:DobotAI 已有 ops/ 下的 deploy_dobotai_prod.sh / rollback_dobotai_prod.sh / prod_verify.sh / prod_last_turn.sh(在生产机 /opt/dobotai/container/ops/)。
  • 要做什么:对照规范 §5.8 / §5.5 逐条核对:产物 sha 校验、迁移列 COUNT 门、agent 配置 hash CAS、flock 互斥、0600 备份。
  • 为什么:规范要求"部分失败后重跑不会双重应用",这是脚本级保证,必须在脚本里看到。
  • 怎么验证:每个门都故意触发一次(喂一个已存在的列 / 错的 sha),确认脚本拒绝执行而不是静默继续。
  • 谁来做:开发(只读复核 + 演练);演练在测试机做。

P2

11. aiball/upper-tool、zheromiku/protocol-docs 是空仓

  • 现状:两个仓库 empty=true。
  • 要做什么:要么初始化(README + .gitignore + 门禁骨架),要么归档。
  • 为什么:空仓出现在仓库列表里,会让人"以为这里该有东西"。
  • 怎么验证:GET /repos/{r} 的 empty=false,或仓库已归档。
  • 谁来做:本人决定去留。

12. docs/提交规范.md 缺失

  • 现状:~/.githooks/commit-msg 与 .gitea/scripts/ci_gate.py 的提示文案都写着"详见 docs/提交规范.md",但仓库里没有这个文件。
  • 要做什么:把规范 §2 的内容落成各仓的 docs/提交规范.md(或把提示文案改成指向本规范)。
  • 为什么:一条指不到地方的指路,比不指路更费时间(原稿 §2.2 的原话)。
  • 怎么验证:test -f docs/提交规范.md 通过;或 grep 提示文案确认已改为可达路径。
  • 谁来做:开发(顺手改)。

13. 规范自身的仓库化(已完成,只剩"各仓加指针")

  • 现状:正本已入仓 —— zheromiku/eng-standards-main,默认分支 main,2 条提交,HEAD 419396f3ce0c;本地 ~/eng-standards/ 的 git rev-parse HEAD 与远端 ls-remote 一致。 ⚠️ 仓名带了 -main 后缀(原计划写的是 eng-standards);文档内 4 处引用已按实际仓名改正,不留指不到的指针。
  • 要做什么:①建仓 ✅ ②push ✅;③ 各仓 AGENTS.md 加一行指针:Weknora/{dobotai-platform, knowledge-governance, knowledge-adapter-service, Enterprise-Knowledge-Base}、aiball/{software-pc, protocol-docs}。
  • 为什么:规范要"不用每次重复说一遍",靠的是可被引用的单一来源(原稿 §11)。先前放在 /srv/aiball/ci/standards/ 下是分类错误 —— 跨仓规范不该挂在单个项目(AI球)的目录里。
  • 怎么验证:git ls-remote --heads origin main 的 SHA == 本地 git rev-parse HEAD;各仓 AGENTS.md 里的指针路径可达。
  • 谁来做:③ 需要改动 6 个仓库,属独立动作 —— 等指示,不自行扩围。

14. aiball 固件(ESP32-P4)的流水线尚未定义

  • 现状:/srv/aiball/firmware 有固件工程,但 Gitea 上没有对应仓库;aiball 组织下只有 protocol-docs / software-pc / upper-tool。
  • 要做什么:固件入仓后,按同一套 §5.1 建固件流水线:idf.py build 一次 → 记录 .bin 的 sha256 → 测试机烧录测试版 → 量产/发布烧同一份 .bin。
  • 为什么:固件同样适用"同一份产物"铁律;烧录"只写不回读",所以产物哈希是唯一可信的同一性证据(AIxProbe 经验)。
  • 怎么验证:sha256sum 两次产物文件一致;烧录日志里的字节数与 OpenOCD wrote 一致。
  • 谁来做:本人定仓库归属 + 开发建流水线。

15. ci-bridge 的公开地址与实际可达性核对

  • 现状:config.json 的 public_base=http://192.168.50.134:8899、public_base_alt=http://100.92.49.78:8899;本次实测 127.0.0.1:8899/healthz 正常(reports:19, previews:7, notify:true)。
  • 要做什么:核对 192.168.50.134 是否仍是本机当前 LAN 地址(网段变化会让所有通知里的链接失效)。
  • 为什么:报告里给的每个 URL 都必须能 200,否则通知等于没发。
  • 怎么验证:curl -m 5 http://192.168.50.134:8899/healthz 与 curl -m 5 http://100.92.49.78:8899/healthz 都返回 ok:true。
  • 谁来做:本人/开发。

16. 规范守门脚本的 Gitea 版(可选)

  • 现状:附件里的 spec-check.mjs 是 GitLab 口径(判据含 glab 占位符、.gitlab-ci.yml、workflow.rules),直接拿来自Gitea 环境跑会假红。
  • 要做什么:改写判据:.gitlab-ci.yml → .gitea/workflows/*.yml;workflow.rules → on: 三类入口;glab-placeholder → giteactl/gitea_api.py 等价约束;resource_group → flock。保留 --self-test 的反向自检。
  • 为什么:规范的"可执行"部分最好变成退出码(原稿 §11.2),但不改写就会假红,而假红和假绿一样要修。
  • 怎么验证:--self-test 造两个夹具(合规全绿、违规每条都红)。
  • 谁来做:开发(本次未做,见任务边界)。

不建议做的事(写下来防止被"顺手加上")

  • ❌ 不要为了能 push 去改 Gitea 凭据/token scope —— 权限没配好要问人,自己换 remote/换账号会把"权限没配好"变成"动作做了一半"。
  • ❌ 不要把测试环境部署塞回 build.yml(CI 流水线只管校验与编译);生产 workflow 就是生产 workflow。 占位作业在填完真实逻辑之前必须红,不许"打印 TODO 然后返回成功"。
  • ❌ 不要给生产 workflow 设 concurrency.cancel-in-progress: true(会取消正在进行的部署,而取消不是回滚)。
  • ❌ 不要在生产与测试同时跑压测(两服共用同一套 RDS,会扰动生产)。
  • ❌ 不要在源码路径里用 dist / data / secrets 这些名字(.gitignore 会静默吞掉)。