# TokEMS 项目协作规则 ## 本地开发与预览 - 主工作目录的 `main` 是本地集成分支。日常页面调整和连续小迭代默认在这里完成,无需每轮新建分支或工作树;本地提交与远端推送分别按用户授权执行。 - 已在本地 `main` 完成的提交,远端推送使用 `HEAD:refs/heads/codex/`,再通过 PR 合并到远端 `main`。用户授权推送后仍须遵守 PR 流程;禁止直接推送远端 `main` 或使用管理员权限跳过必需检查。 - 用户已授权在本仓库默认以管理员身份合并 PR,无需等待审核者批准或再次确认。合并前仍须确认目标 PR、提交 SHA 和全部必需 CI 检查通过;管理员合并仅跳过审核者批准要求。 - 经明确授权的临时依赖审计例外、适用范围与到期门禁记录在 `docs/security-audit-exceptions.md`。禁止扩大忽略范围;到期、依赖路径改变或官方修复可用时必须重新处理。 - 需要并行隔离、较大实验或用户指定时才使用功能分支与独立工作树。完成并验证后及时合并到本地 `main`,再更新共享预览。 - `http://127.0.0.1:8088/`、Compose 项目 `tokems` 和 `tokems-*:local` 镜像只用于主工作目录的共享预览。其他工作树不得构建、启动或替换这套共享服务。 - 独立预览必须同时隔离 Compose 项目名、镜像标签、端口和数据卷;仅创建 Git 分支或工作树不能隔离运行环境。临时构建与测试优先使用不接管共享服务的验证方式。 - 合并前检查所有工作树与未提交修改,只整合已完成的内容,保留正在进行的编辑。历史备份和仍在使用的工作树未经确认不得删除。 - 更新共享预览前核对构建提交、当前运行版本与本地环境配置,保持已有数据库和素材。页面更新后验证实际运行版本和页面效果。 ## 生产发布 - 生产发布前必须阅读 `docs/production-deployment-runbook.md`。 - 唯一上游仓库为 `https://github.com/yaojingang/TokEMS.git`,生产代码只允许来自已合并且 CI 通过的 `origin/main`。 - 生产目标 SHA 必须等于一个以 `main` 为目标分支的已合并 PR 的 `merge_commit_sha`,并具有该 SHA 的成功主分支 CI 和完整镜像发布。确认提交已在远端 `main` 后,还须核对这三项证据才能给出可发布结论。 - 生产服务器源码目录为 `/www/wwwroot/TokEMS`。宝塔站点目录 `/www/dk_project/wwwroot/hui.ailingdaoli.com` 只承载站点和反向代理配置,禁止在该目录拉取代码、构建镜像或执行数据库迁移。 - 生产环境文件固定为 `/etc/tokems/production.env`,目录权限为 `root:root 0700`,文件权限为 `root:root 0600`。生产 Compose 和发布脚本禁止读取 Git 工作区中的实时 `.env`。 - 服务器分支 `production` 跟踪 `origin/main`。发布前确认工作区干净,并确认服务器 `HEAD` 与 `origin/main` 完全一致。 - 每次生产变更都要先创建数据库备份、记录当前提交和容器状态,并为当前应用镜像添加 `rollback-<时间戳>` 标签。 - Docker 构建和运行必须使用同一组 `BUILD_SHA`、`BUILD_TIME`、`BUILD_MIGRATION`、`BUILD_MIGRATION_HASH`。任何值为 `unknown` 时禁止切换生产流量。 - 标准生产发布只使用 `.github/workflows/publish-images.yml` 写入私有包 `ghcr.io/yaojingang/tokems-production-private` 的预构建镜像。历史包 `ghcr.io/yaojingang/tokems` 与 `ghcr.io/yaojingang/tokems-production` 禁止进入生产发布。`release-` descriptor 必须最后发布,并固定目标平台、四项 `BUILD_*` 和六个服务 digest;生产机验证 GitHub provenance 后才能更新 `tokems-*:local`。 - Release descriptor schema 2 同时携带目标提交的完整 Git Bundle 和 descriptor verifier,并固定两者 SHA-256。生产机只允许在 descriptor provenance、Bundle 目标 ref、目标 SHA 和 Fast-forward 历史全部通过后更新 `refs/remotes/origin/main`;标准发布不得依赖生产机直连 `github.com` Git Smart HTTP。 - `/etc/tokems/ghcr-read-token` 仅保存 `read:packages` PAT classic,权限固定为 `root:root 0600`。临时 Docker 登录目录只允许位于 `/run/lock/tokems-production-deploy`,发布日志和证据不得包含 Token。 - `--build-on-host` 只作为人工应急入口,继续执行 10 GiB 构建内存门禁。自动化受限入口不得传入该参数。 - 用户已批准只增强原 `tooling/production-deploy.sh` 的网络层:可选 `--proxy` 仅用于 GitHub 校验、provenance 和镜像下载。保留原备份、支付保护、规范同步、迁移、写冻结及验收流程;不启用蓝绿、不重启或修改 Docker 守护进程。代理只接受 SSH 回环地址,下载失败不得回退直连,完整镜像摘要验证后才能本地导入。 - 普通发布必须在预检、停服前和停服后核验支付结清;存在进行中交易、待确认通知或已付款缺票时不得继续迁移。停服后发现竞态,只能在数据库尚未变更且原版本身份核验通过时恢复原容器并取消发布;不得借用 `--resume-recovery` 绕过普通发布门禁。 - 常规发布固定使用 `SEED_DEMO_DATA=false`。只有已确认需要同步仓库规范模板时,才允许按 Runbook 的“规范模板同步”流程临时运行 `SEED_DEMO_DATA=true`。 - 自动检测到规范漂移或显式执行 `deploy --sync-canonical` 时,目标规范快照与当前运行提交完全一致,且目标差异仅包含部署脚本、部署测试、协作文档或运维文档,脚本允许复用当前已验证镜像完成规范同步。该流程仍要执行数据库备份、写冻结、生产数据保护和完整验收;其余目标使用通过证明的预构建镜像。 - 自动发布预检必须以只读数据库连接导出生产完整规范快照并与目标提交比较;Git 快照变化或生产状态漂移时都要启用规范同步,`--skip-canonical` 不得跳过漂移修复。 - 规范模板的组织 slug 为 `geo-conference`,大会 slug 为 `tokems26`。线上报名、订单、票、发票、库存销量和用户数据必须保留。 - 主工作目录共享预览中的 `geo-conference` / `tokems26` 是唯一规范大会模板,独立页面为 `http://127.0.0.1:8088/tokems26`。规范环境保留该大会的默认业务绑定,根首页可以展示大会或留空。首页文案、导航或关联后台设置发生任何变化后,推送 GitHub 前必须运行 `pnpm canonical:export`,并提交完整规范快照 `packages/contracts/src/canonical-homepage.snapshot.json` 及前台派生快照 `packages/contracts/src/canonical-homepage.public.json`。 - 每次推送 GitHub 前都必须运行 `pnpm canonical:check`。本地首页、数据库或当前发布快照不可读取,快照存在漂移,或脱敏校验失败时禁止推送。 - `pnpm install` 会启用仓库内 `.githooks/pre-push` 门禁。门禁会核对实时规范状态、受保护文件的工作区清洁度,以及实际待推送提交中的快照与同步逻辑;禁止绕过该门禁推送。 - 规范快照包含当前公开发布内容,以及大会基础设置、模板草稿、当前指针引用的发布版本、首页绑定、票种定义与容量、报名表、嘉宾、议程、FAQ、SEO、公开站点设置、蓝图、核销清单、通知模板、AI 文案提示、模板素材和所有被纳入模板定义引用的 HTML 文档。未被当前发布、绑定或默认设置引用的历史版本,以及销量、报名用户、会员资料、订单、支付、票证、发票和审计记录不得进入快照。 - 管理员账号、姓名、邮箱、密码、权限身份,以及 API 地址、密钥、令牌、Cookie、第三方集成、支付、短信和对象存储凭据不得进入规范快照。管理员信息继续只从部署环境读取。 - 禁止把 `git reset --hard`、`git clean`、`docker system prune`、`docker compose down -v`、删卷、清库或数据库覆盖恢复写入常规发布流程。 - 解除生产写冻结前必须启动独立的 systemd 监督单元;恢复标记仍存在且部署控制器退出时,该单元持续停止 API 和 Worker,直至确认写容器已经停止。 - 发布完成后必须同时验证容器健康、服务器本机 HTTP、公网 HTTP、构建版本、迁移哈希、公开大会内容和生产数据计数。 - `.env`、数据库连接、密钥、令牌和第三方凭据不得写入 Git、日志、Issue、PR 或发布记录。检查环境时只输出允许公开的键。 ## 蓝绿发布入口的独立规则 - 用户已批准新增 `tooling/production-bluegreen.sh`,保留原 `tooling/production-deploy.sh` 的业务发布流程;旧入口仅允许上文明确批准的可选代理网络增强。蓝绿入口执行 `docs/production-bluegreen-deployment.md`;上文关于原入口的 canonical 漂移同步、写冻结、db-init、thaw watchdog 及覆盖 `:local` 标签的要求不套用到蓝绿流程。 - 蓝绿切换只能在 Docker Gateway 内完成;宿主机宝塔 Nginx 保持固定 `127.0.0.1:8088`,禁止发布脚本修改或重载宿主机 Nginx。首次接管旧只读 Gateway 允许在镜像与候选环境就绪后短暂交接入口端口,后续只热重载常驻入口容器。 - 蓝绿发布只使用同样经过 main PR、CI、descriptor、Bundle 和 provenance 验证的私有预构建镜像。完整下载、验证、容量检查和更新分类必须先于任何应用停启、数据库更新和切流量。 - 蓝绿下载可显式使用 SSH 回环代理;代理环境只传入准备阶段的网络客户端,不进入业务容器、验收或恢复。代理拉取使用 `crane` 加本地导入,保留 provenance 和全部摘要验证,不自动改写或重启 Docker 守护进程,也不在代理失败时回退直连。 - 迁移/填充按目标提交 `tooling/bluegreen/release-policy.json` 与数据库账本分类;未知或未审核的变更在停服前拒绝。普通代码发布保持可写,维护更新停止全部旧写容器后执行。 - 蓝绿发布不 seed、不对生产 canonical JSON 做全等、不覆盖生产协议与默认模板设置。规范快照继续用于本地、CI 和推送前检查;内容更新采用后台发布或明确的版本化事务任务。 - API 定时任务和 Worker 必须只有一个后台所有者。候选先 standby;交接前排空旧任务并证明旧写容器停止。使用 systemd 控制器、root 私有恢复账本和本地已验证镜像恢复,不把恢复写能力绑定到最新远端 CI。 - 新旧入口共用互斥锁和恢复标记。不得重放已回滚或被后续发布替代的旧记录;不得自动覆盖恢复数据库、强杀未完成任务、删除数据卷或清理旧回滚资料。 ## 发布记录 - 每次正式发布从 `docs/release-records/TEMPLATE.md` 创建一份日期化记录。 - 发布记录包含目标提交、最高迁移、备份位置、镜像回滚标签、执行结果、验证证据、异常和剩余风险。 - 历史记录只描述当次事实。后续发布以当前 Git、CI、服务器健康接口和 `docs/production-deployment-runbook.md` 为准。 ## 网站统计隔离 - 根首页展示方式与默认业务大会分别保存。根首页留空时保留默认业务大会及历史报名、FAQ、合作入口;配置冲突必须拒绝覆盖。空白根页面由服务端直接返回,不执行应用脚本或统计脚本;站内进入根路径必须创建新文档。 - 同一路径和查询参数下的页内锚点变化保留当前文档;根路径导航门禁必须放行这类变化。首页所有可用锚点必须有对应目标,并通过桌面和手机菜单回归验证。 - 顶部菜单按大会导航区块统一解析,首页、合作页及公共导航共用配置。未配置菜单时继承模板,显式空数组表示隐藏全部链接;保存、模板发布和合并后均校验链接与区块引用。 - 报名、账户、订单、发票、票证、独立支付、后台和 API 路径禁止加载网站统计脚本。 - 公开区域与敏感区域之间的前端导航必须创建新文档,避免已执行的第三方脚本或敏感页面内存跨越边界。 - 新增或调整公开路由时同步更新统计路径分类、整页边界测试和真实 Head 验收。