zizi 7de582e4c7 docs(distill): Lane D2 Round1 学习蒸馏回填——4 处就近落档(split-brain铁律/隔离-D真验/localStorage走查/防悬空提交)
把 Round1 四条已验证学习整合进既有文件(就近插入·保持风格·零孤儿新文件):
- saa-graph-orchestration §6:铁律「worker succeeded ≠ 准予发布」(split-brain 防线)——九门 runnableOk=机制可玩 ≠ 准予发布,发布裁决归治理层,生产化前安全门由 W-G1 GP9 接管(来源 Lane B agent-loop-v1 退役登记)
- staging-ops §3:配方「隔离实例 + -D 注入真验 feature-flagged 后端改动」——起 :48090 隔离实例、JVM -D 注开关+safety baseUrl/key/model,零改 repo/yaml、live 不动(来源 Lane E G1 GP9 10/10 真验)
- ui-walkthrough-cdp §3:小配方「localStorage 注入 token 过 requiresAuth 走查」——免登录直达受保护页只读走查(来源 Lane E G0)
- 2026-06-16-生成引擎-并行编排 §3:硬规则#7「ultracode 并行 worktree 防悬空提交」——git ops 必须 git -C <worktree>、禁 commit 主 checkout、主 agent 推送前核验 commit 真在其分支(来源 Lane E 错落成悬空 commit 已 cherry-pick 救回)

README 索引无需动(4 处均为既有文件内容补充,非结构性增删改名)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:10:05 +00:00

7.9 KiB
Raw Blame History

staging 运维配方(机器分工 / 代码同步 / 重部署 / 构建门 / 冒烟)

staging 全栈在 mini-desktop100.64.0.7huijing 单体 :48080 + game-studio :4173 + game-admin :4174 + 隔离 MySQL/Redis 容器共享基建Gitea/MySQL/Redis/MinIO/new-apimini-infra100.64.0.8。 本配方由 2026-06-09~11 多波实战蒸馏M1 真跑 / 黄金闭环 / UI 走查 / Wave4 集成门);红线类条目同步收录于 ../rules/engineering-conventions.md。真 UI 走查另见 ui-walkthrough-cdp.md

1. 机器分工铁律(四机)

  • 创始人本地工作站 → lili-macM1 Pro / 32G / ARM不入 Tailscale 调度,会休眠合盖):跑 Claude Code 主会话、本地全栈 dev、本地浏览器/CDP 快走查mvn/npm 快构建迭代。两条边界:① ARM≠x86,Mac 产出的 JAR/前端 bundle 架构中立可用,但 Docker 镜像 + smoke 门必须在 mini-desktop x86 出(否则镜像架构错、与 prod 不同构=半假门);② Mac 上 CDP 只算"快走查"加速开发,e2e 验收门仍只认 mini-desktop 结果(服务+浏览器同机 localhost,见 game-e2e-cdp-harness.md)。
  • 权威验收 / 重型构建 / 测试 / staging app / 浏览器 e2e 门 → mini-desktop15Gjava17 + mvn3.8.7 + docker + node22 + chrome146与 prod 同构)。
  • 常驻无人值守 → 6c6g:常开的 agent 编排/Workflow、cron 定时、后台批跑、git 操作Mac 会休眠故常驻活只能留此)。禁跑重活:重型前端构建 OOM、chrome 连续 exit 144。元规则:同一失败签名第二次出现 → 换机器,不再换启动姿势。
  • 共享基建 → mini-infra(绝不在其上跑项目 app / 重型构建;缺 RocketMQ+NacosMVP 未部署)。

2. 代码同步(分类器约束)

  • scp/rsync 源码树会被分类器语义拦截settings 放行也没用)。正解 = git push 到 Gitea → mini-desktop 匿名 HTTP clone/pullhttp://101.200.34.71:3000/zizi-al/games-development-ai.git:3000 HTTP 匿名读,非 :2222 SSH
  • 单文件传输:cat local | ssh mini-desktop 'cat >/tmp/x'(分类器不拦单文件)。
  • 远程脚本省心写法:ssh mini-desktop 'bash -ls' <<'REMOTE' ... REMOTE-l 拿 PATH-s 读 stdin免引号地狱
  • push 竞态与管道掩码2026-06-12 实翻):①大资产 push 在途时再发 push 会撞 Gitea ref 锁(remote rejected (failed to update ref)/failed to push some refs)——同仓 push 串行化,等上一笔落地(git ls-remote 核)再发;②git push 2>&1 | tail -1 的退出码=tail 恒 0会吞掉推送失败——push 不接管道,要么裸跑判 $?,要么 tee+PIPESTATUS[0]。每次 push 后以 git ls-remote origin <branch> 实证远端头,不信本地输出。

3. 后端重部署标准序(授权窗口内执行)

教训:~/game-staging/repo 曾是 stale 克隆,「构建源 ≠ 运行 jar」翻过车——每次部署按此序以字节码实证收口。

  1. 备份运行 jar 到 /tmp
  2. 清本地独有 untrackedapplication-staging.yaml 以 origin 版为准——origin 是含 executor/passport 段的超集);
  3. git reset --hard origin/dev/2.0.0
  4. mvn clean install -pl huijing-server -am -DskipTestswarm .m2 约 33s
  5. jar 字节码实证含本次修改unzip -p <fat.jar> BOOT-INF/lib/<模块>*.jar 核对 .class
  6. start-app.sh 重启 → 验 health 200 / 四模板 banner / Flyway up-to-date / admin-api 200M1 无回归)。

高风险/整机重部署安全变体——隔离验证后再切2026-06-16 整机改新命名空间 com.wanxiang.huijing 实证):步 4 构建出新 jar 后,先用新 jar 在隔离端口(如 :48090+ staging profile 起一个实例,live :48080 全程不动;在隔离实例上验全Flyway 全绿无冲突 / health 200 / 本波新端点逐个 200 code=0 / 免短信登录拿 token隔离验全过才切:停老 → start-app.sh 起新 → 复验(同上 + smoke-test.sh)。任一步 fail → 停新、用 /tmp 备份 jar 恢复 :48080 → 确认 live 恢复。严禁无隔离验证就切 live;备份 jar 留到复验全过再删。 注:start-app.sh/模块名随命名空间改名已更新(huijing-server,重部署前核对 jar 路径与现命名空间一致。

隔离实例 + -D 注入「真验 feature-flagged 后端改动」(不切 live、零改 repo/yaml——2026-06-16 Lane E G1 实证GP9 10/10 真验即用此法):要在 staging 真跑一个默认关闭的 feature-flag 后端改动(验它打开后行为对、关着时现行字节不变),不要改 repo 里的 application-staging.yaml、也不要重部署 live。配方:用已部署的 jar(或步 4 新 jar隔离端口(如 :48090)起一个实例,开关与外部依赖全经 JVM -D 注入,例:

java -jar <fat.jar> --server.port=48090 --spring.profiles.active=staging \
  -Daigc.control-plane.enabled=true \
  -Daigc.safety.base-url=http://100.64.0.8:3000 -Daigc.safety.api-key=<key> -Daigc.safety.model=<model>

Spring 的 -D/--key=val 优先级高于 yaml,故开关与 baseUrl/key/model 临时注入即生效,repo 与 live 实例一行不动。在此隔离实例上跑负例集真验(如 10 条恶意 brief 全被 GP9 拦),验完即停,flag 在主干仍默认关 = 现行字节零变。与上一条「整机重部署安全变体」互补:那条是"新 jar 验全过才切 live",这条是"现行字节不动、只临时验一个 flag 行为"。

教训速记(区分两个隔离用法):同样起 :48090 隔离实例——「重部署安全变体」目标是最终要切 live(验全过 → 停老起新);「-D 注入真验 flag」目标是永不切 live(只验 flag 行为,验完即停,主干字节不变)。混用会误把"只想验 flag"做成了"切 live"。

4. 构建/测试门(红线)

  • vue-tsc --noEmit 是假门禁,前端验证一律 npm run build
  • mini-desktop 构建 game-studio 必须 npm run build -- --mode stagingvite preview 直接 serve 工作树 dist默认 build = 事实上改部署、mock 中间件接管且无 warn
  • huijing 前端game-admin稳定配方pnpm9corepack prepare pnpm@9.15.4 --activate,一举绕开 pnpm10+ 的 lockfile 镜像校验与构建脚本审批两道坎)+ 前端目录 .npmrc 设 npmmirror → node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build(绕 pnpm-run 预检。node_modules 腐化(如混入 vite8 / 杂散 pnpm-workspace.yaml 报 packages 缺失)→ 移开杂散文件 → 清装精确回钉版本。
  • huijing-module-system 测试:SPRING_DATA_REDIS_PORT=26379 mvn test ...(宿主 16379 被 staging redis 占用带密码,嵌入式 RedisServer 失败被吞 → NOAUTH 假红)。
  • mini-desktop 长驻 serve/后台进程2026-06-11 T1-spike 双 lane 实证ssh 会话内 nohup &/setsid 仍可能随会话 teardown 被 SIGHUP 连带杀(症状=稍后访问 ERR_CONNECTION_REFUSED。稳定配方首选 systemd-run --unit=<name> 起 durable 单元;次选独立 launcher setsid bash -c 'exec node serve.cjs' 双脱离 + 起服后 5×6s 探活门curl 200 连续过)确认常驻再继续。另:长任务后台进程严禁与 pkill/curl 写进同一 heredoc 串行(竞态留孤儿进程占 pid 不占端口)。

5. 冒烟门

  • API 就绪门:deploy/smoke-test.sh(只读 12 项)+ --deep13 项含 generate 入队),含 CORS/鉴权test1 token验证。
  • gotchafeed item 的 packageUrl 恒 null真实取包走 GET /app-api/runtime/package/{versionId}
  • API 全绿 ≠ UI 通:编排器旁路会掩盖 UI 缺陷,用户可见波次收口前必须做一次真 UI 走查(见 ui-walkthrough-cdp.md)。