t 3b26457165 docs: 抬档门禁 + 1.0.0 前置(稳定契约承诺)
- **抬哪一档成为硬门禁**:破坏性条数取**目标提交里候选那一段** ⇒ `0.x` 有破坏性必须抬**次版本**(或主版本),
  `≥1.0.0` 有破坏性必须抬**主版本**;只抬修订/抬次不够都阻断。无破坏性时抬哪档不限,
  但候选号必须严格大于上一正式版与当前开发号(号只增不减)。
- **`1.0.0` 首见的前置**:《稳定契约承诺》必须写实(接口 / 数据模型 / 配置 / CLI 输出与退出码,
  不留 `待填`/`TODO`/`TBD`)并在 `## [1.0.0]` 记录里链接它;`1.x → 2.0.0` 不重复要求。
- 同步:正本 §6 五次修正(⑭⑮)、07 发版判据表、"抬哪一档"对照表、templates/release-preflight.py、
  templates/README.md、04 §M(V-14~V-17)。

验证:templates/release-preflight.py --self-test 32 分支全过;试点仓夹具 91/0、make verify 15/15。
2026-10-13 17:13:44 +08:00

Gitea 版工程规范(eng-standards 适配版)

性质:跨仓库的系统级规范,按本机真实环境(自建 Gitea 1.26.2 + act_runner + ci-bridge + 阿里云测试/生产)改写。 来源:评估并适配 eng-standards-main.zip(原稿是 GitLab/glab 口径),模板问题与修正见 04-模板评估与修正.md。 状态:本次只制定规范。不部署生产、不运行附件原脚本、不改任何仓库。 正本仓库:zheromiku/eng-standards-main(Gitea,https://gitea.zheromiku.top/zheromiku/eng-standards-main);本机工作副本 ~/eng-standards/。

怎么读:README 三十秒版 → 01-规范 全文 → 02-流程说明与Runbook(怎么操作)→ 03-待配置事项(还差什么)→ 04-模板评估与修正(原稿哪里不对)→ 05-应用机制(怎么让它以后默认生效)→ 06-接入既有工程(手头这个仓怎么接进来)→ 07-发版操作说明(打 tag 与建 Release 的步骤)。

交付物

文件 是什么
README.md 本文件:索引 + 三十秒版 + 本环境唯一取值表
01-规范-Git与CI-CD(Gitea版).md 正本:分支/提交/评审/触发、自动检查与测试环境部署、生产发布与回滚、版本与产物
02-流程说明与Runbook.md 日常动作的逐步命令(提交前、看 CI、接入新仓、发布、回滚)
03-待配置事项.md 逐项:现状 / 要做什么 / 为什么 / 怎么验证 / 谁来做
04-模板评估与修正.md 附件 15 处问题的证据与改法(含实测反证)
05-应用机制-让规范在以后所有工程生效.md 三渠道(技能 / 仓内指针 / 生成器+守门)、已配 vs 待配、验证记录
06-接入既有工程.md 既有仓怎么接进来:前置体检(含 PR 锁死陷阱)、一条命令、试点记录、验收判据
07-发版操作说明(tag与Release).md 怎么发版:三态区分、四类小节变更记录(含破坏性变化的固定写法)、构建身份、只读预检、批准后打注释 tag + 建 Release 与读回判据、常见错误表
templates/ 可直接落仓的骨架:gitea-build.yml(只做 CI)、gitea-prod-deploy.yml(人工发起;未实现的步骤故意红)、gitignore、commit-msg、ci_gate.py、ci_report.py、README.md(内含 AGENTS.md 骨架)
scripts/new-project.sh 新工程生成器:一条命令产出默认合规的骨架(CI + 门禁 + 提交规范;已端到端测过)
scripts/adopt-existing.py 既有工程接入器:体检 → 加指针(建 PR 后停下等你批准)→ 开保护(幂等,默认 DRY-RUN);--merge-pr <n> 才是显式批准的合并
docs/architecture/ 两份设计依据草案:universal-ci-standard.md(通用 CI 规范)、knowledge-governance-ci-pilot.md(试点交接)。已生效的部分在 01-规范 里;它们是过程记录,不是配置

0. 三十秒版(只记六句)

  1. 结论只来自可复现的命令。数字、清单、成败一律由脚本打印或断言,禁止手抄进文档(原稿 §0-1,保留)。
  2. 每个校验都要有反向自检:故意弄坏一处,它必须红。永远返回 0 的校验器比没有校验更糟。
  3. 密钥只从 Gitea Secrets / 目标机文件进,不入库、不回显、不进命令行参数(会进 ps)。
  4. 提交前跑本仓门禁命令(唯一入口,如 make verify);CI 不是第一次验证,CI 只是"再来一遍"。 CI 与 CD 分开:推送流水线只做检查/测试/构建/证据,不含部署;部署由每个项目自己设计。
  5. 生产部署只部署"测试验收过的那一份产物"(同 sha、同镜像 ID)。这条是本环境新增的硬约束,见 §6.1。
  6. 占位不许假报成功:没实现的步骤要 exit 1(红的占位是设计),不要"打印 TODO 然后返回成功"。

1. 本环境事实(唯一取值表;以命令输出为准,不要手抄到别处)

# 取这张表的命令(改完环境重跑,别靠记忆)
python3 ~/.hermes/scripts/gitea_api.py GET /api/v1/version
python3 ~/.hermes/scripts/gitea_api.py GET /api/v1/repos/search?limit=50
docker ps --format '{{.Names}}\t{{.Image}}' | grep -E 'runner|bridge'
curl -s http://127.0.0.1:8899/healthz
项 值
Gitea 自建 1.26.2;LAN http://192.168.50.223:3000;公网别名 https://gitea.zheromiku.top
账号 / 组织 zheromiku;组织 Weknora、aiball
仓库 Weknora/{dobotai-platform, knowledge-governance, knowledge-adapter-service, Enterprise-Knowledge-Base};aiball/{protocol-docs, software-pc, upper-tool(空)};zheromiku/{hello, protocol-docs(空)}
CI 引擎 Gitea Actions(act_runner,仓库级 Runner 容器)
Runner runner-weknora-kg-01→knowledge-governance、runner-weknora-dp-01→dobotai-platform、runner-weknora-ka-01→knowledge-adapter-service、runner-software-01(aiball 组织级,覆盖 protocol-docs/software-pc)
Runner 配置 capacity: 1(同时只跑 1 个作业)、force_pull: false、labels ubuntu-latest/24.04/22.04 → docker://docker.gitea.com/runner-images:*、注册令牌文件挂载(/run/secrets/registration_token:ro)、挂 docker.sock
工具链/缓存 主机 /srv/aiball/ci/toolcache 只读挂载为容器内 /opt/citools;可写缓存 /srv/aiball/ci/toolcache/cache → /opt/citools-cache
ci-bridge /srv/aiball/ci/bridge/bridge.py,监听 0.0.0.0:8899;容器内可达地址 http://172.17.0.1:8899;局域网 http://192.168.50.134:8899;Tailscale http://100.92.49.78:8899
bridge 接口 POST /api/ci/report(作业结果→落盘+微信通知)、POST /api/ci/publish(静态产物 tar.gz→URL)、GET /p/<ns>/<repo>/<sha>/…、GET /r/<id>、GET /healthz
bridge 落盘 报告 /srv/aiball/ci/reports/(含 pending/、undelivered/);预览 /srv/aiball/ci/previews/
仓库变量/密钥 CI_BRIDGE_URL(variable)、CI_BRIDGE_TOKEN(secret)——仅 Weknora 三仓已配
提交闸门 本机 hook ~/.githooks/commit-msg(core.hooksPath)+ CI 侧 .gitea/scripts/ci_gate.py(同一套规则,绕不过)
仓库接入脚本 /srv/aiball/runner/attach_repo.sh <owner/repo> <runner-name>、/srv/aiball/runner/deploy_repo_runner.sh
Gitea API 客户端 ~/.hermes/scripts/gitea_api.py(库/CLI)、~/.local/bin/giteactl(runs/show/logs/watch/rerun)、giteacli(只读用途,本机 token 无 read:user)
测试服务器 阿里云 ECS 120.76.217.51(key ~/.ssh/weknora-aliyun-test-ed25519)
生产服务器 阿里云 ECS 120.76.218.137(key ~/.ssh/weknora-aliyun-prod-ed25519)
生产布局 /opt/dobotai/{config/dobotai.env, container/{compose.yaml,runtime.env,migrations/,backups/,ops/}, secrets/};镜像由 container/runtime.env 的 DOBOTAI_IMAGE= 选择
健康/版本 http://127.0.0.1:8090/healthz({"status":"ok"})、http://127.0.0.1:8090/version(version/commit_sha/build_time)
数据库 永远是阿里云 RDS(PostgreSQL 17.9);目标机 Docker 只跑应用容器,禁止本地库
构建受限 目标机 不可达 Docker Hub → 用 daocloud 镜像源;Go 用 GOPROXY=https://goproxy.cn,direct
本机网络 出网走 mihomo;境外全 000 时先查 ~/.clashctl 节点(PUT /proxies/三毛机场 {"name":"<活节点>"})

⚠️ 上表里只有一个数字是"规范"(如"生产路径 /opt/dobotai"),其余都是"现状快照"。现状会漂;所以每项都给了取数命令。


本地自检(不需要连 CI,可直接跑)

# 通用门禁模板:汇总 / 前端判据 / pytest 退出码语义 / 完整 SHA / 清单比对
python3 templates/ci-gate.py --self-test

# 上报核对(缺项/重复/未知项/短 SHA/档案/运行模式)
python3 templates/ci_report.py --self-test

# 预览脚本的打包判定(空产物 / 缺 index.html 必须被拒)
python3 templates/ci_preview.py --self-test

# 提交范围取法(截断/空范围/新分支/手工运行/shallow)
python3 templates/ci_gate.py --self-test

# 检出脚本的协议保留(https 不许被降级;未知协议拒绝;URL 不带凭据)
GITHUB_SERVER_URL=https://gitea.example.com GITHUB_REPOSITORY=owner/repo \
  bash templates/ci_checkout.sh --print-remote

# 合并:判定纯函数 + 真实调用链(假 Gitea,断言 merge 请求发没发)
python3 scripts/adopt-existing.py --self-test
python3 scripts/adopt-existing.py --self-test-chain

# 生成器端到端
bash scripts/new-project.sh /tmp/probe Weknora/probe r1 && ls /tmp/probe/.gitea/scripts

⚠️ templates/ci_report.py --self-test 在规范仓里会因为找不到 scripts/ci_checks.py (实现随项目走)而明确报"自检跑不了"—— 那是故意的:不许拿一份空清单去跑出莫名其妙的结论。

完整调用链(在项目仓里跑:空工作区 → 最小 bootstrap → 仓内脚本 → 提交范围闸门)

python3 scripts/ci_chain_fixture.py

它起一个本地 HTTP git 服务,并把 workflow 里 bootstrap 那段 run: 原样抽出来在空目录里执行 (所以 YAML 一旦改坏,这里立刻红):正例验证"空工作区能启动、检出到事件完整 SHA、协议保留、 新分支范围非空、合规提交通过",负例复现"第一步调用仓内脚本 = 127"、"取不到事件 SHA 必须失败"、 "含违规提交的新分支判红且红在那条提交上"。

⚠️ 模板 workflow 的第一步必须是最小 bootstrap(只依赖 runner 给的环境变量): 空工作区里仓内脚本还不存在 —— grep -n "name: 检出代码" -A3 templates/gitea-build.yml 可核对。

S
Description
No description provided
Readme 1.1 MiB
Languages
Python 92.1%
Shell 7.9%