lili a207cb8d65
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
docs(agents): skill 规范化双层收口 + 席位context skill 新增 + W-NSTAR/W-TPL/W-GENLOG 设计波落档
- .agents/skills 25 件全量 frontmatter 规范化与评审修入(含 prompt-governance 大修);.claude/skills 7 件薄壳按双层方案①落位
- 新增 skill:agentic-seat-context-design(agentic 席位与 context 工程设计基线,2026-07-05 探索蒸馏)
- 设计波三件落档:复杂游戏北极星件(W-NSTAR 终审稿待拍)/黄金模板规格件(W-TPL 定稿待批)/生成侧过程蒸馏回路(W-GENLOG 骨架)
- protocol/在飞板/作战清单/数据飞轮 SoT/契约 prompts 索引同步;breakout 九门证据刷新
- .gitignore 补 /localagents.md 真实忽略行(该文件自声明绝不提交,此前声明未被机器执行)
- 刻意不入库:nacos-data/ 与 _tier2-gen、c2v-*、amgen-* 生成产物(可重生成,忽略行格式待拍)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 05:32:56 -07:00

26 KiB
Raw Blame History

name, description
name description
staging-ops 在 mini-desktop/mini-infra 上做 staging 或内测 dev 的部署运维时使用:机器分工铁律、代码同步(git push→Gitea clone)、后端重部署标准序、构建门/冒烟门、观测栈起容器、生成线环境地图与 executor 接线的实战配方与踩坑。

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

staging 全栈在 mini-desktop100.64.0.7huijing 单体 :48080 + game-studio :4173 + game-admin :4174 + 隔离 MySQL/Redis 容器共享基建Gitea/MySQL/Redis/MinIO/new-api/Nacos/RocketMQ/观测栈五件 Collector/Tempo/Prometheus/Grafana/Lokimini-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 / 重型构建Nacos/RocketMQ 已自托管部署2026-07-01

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

  • 从 Claude Code 环境 ssh 内网(2026-06-21 实证):ssh mini-desktop 别名会被解析到陈旧代理段 198.18.0.7、port 22 被关(Connection closed by 198.18.0.7 port 22,exit 255),Bash 沙箱开/关都一样。正解 = 直连 Tailscale IP + 禁 ProxyCommand/Jump + 关沙箱:ssh -o ProxyCommand=none -o ProxyJump=none -o StrictHostKeyChecking=accept-new root@100.64.0.7 ...,且 Bash 工具设 dangerouslyDisableSandbox。其它内网机(new-api 100.64.0.8 等)同理用直连 IP,别用可能陈旧的主机别名。

  • 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"。

后端接 staging 前环境检查:代理劫持防护(创始人 2026-06-22 历史回收判定捡回·边际登记)。staging 机若装了 mihomo 之类代理客户端(占 7890/9090),Java 进程连内网 MySQL/Redis 可能被代理拦截,表现为莫名其妙的连接失败。接线前先把内网网段 100.64.0.0/10 加进 no_proxy/JVM nonProxyHosts,放行内网中间件连接。(与生成域 new-api 出网调模型的 no_proxy 是两个场景:那条放行出网,这条放行内网。)

边际登记(创始人 2026-06-22 历史回收判定,真部署时补,不在此展开):① 快检部署落点(运维 033)——deploy/smoke-test.sh 等就绪快检在哪台机怎么跑,真部署时在本配方 §5 补;② 观测数据保留期(运维 034)——第一波已定基础保留期(Prometheus/Loki 15 天、Tempo 7 天,见 deploy/infra/observability/ 及 §6);与 security-and-reliability.md §6 日志保留期(ERROR/WARN 90 天、INFO 30 天)、磁盘水位告警(运维 021)、¥500/月监控预算(运维 027)的完整对账,待后续波观测真接数据后收口;③ staging 数据脱敏子集归属(运维 006)——真上线后 staging 要不要用生产数据脱敏子集来验(暴露真实数据分布下的 bug),是运维-合规交叉约束,待定(现状 staging 是 seed 假数据,可幂等重建)。

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

  • vue-tsc --noEmit 是假门禁,前端验证一律 npm run build
  • mini-desktop 构建 game-studio 必须 npm run build -- --mode stagingvite preview 直接 serve 工作树 dist默认 build = 事实上改部署)。--mode staging 的实证后果2026-06-21 bug#4 钉死).env.stagingVITE_API_BASE 不被加载 → axios baseURL 烤成空串 → 所有 /app-api/* 打到前端 origin:4173),而 vite preview 不代理 /app-apiproxy 仅 dev 生效)、SPA fallback 对未知路径回 index.htmlHTTP 200。后果链getRuntimePackage 拿到 HTML 字符串 → request.ts 拦截器对「非 {code} 包络」直接透传 body 不报错 → respVO 是字符串 → respVO.manifestUrl undefined → resolvePackage 静默走 demo clicker 兜底(无 warn)→ demo startRuntime 抛「template system under reconstruction」→ game_error → /play 显示「游戏加载失败」。排障锚CDP 抓包看 package 请求是否打到 :48080(应有,且应顺带一条 .../manifest 请求grep dist create({baseURL: 应为 http://<后端>:48080 而非空串。
  • 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}
  • feed 流端点语义2026-07-05 真机坐实,防 R5 式假警报):主混合流 GET /app-api/feed/stream 只收 cursor+size无 zoneId 参,恒服务 zone0带 zoneId 的专区流是另一个端点 GET /app-api/feed/zone/stream?zoneId=N。给 /feed/stream 传 zoneId 会被静默忽略(曾据此误判「新游戏不在流」)。size@Max=20超限校验失败返空 data 而非报错——排「流空」先核 size。发布编排创始人「汇入主混合流」对每次发布双写 zone0 主流基线 + 若创作者选非零专区再补写该专区(PublishOrchestrationServiceImpl.writePublishBaseline),故一款游戏可同时现于主流与其专区;新游戏 sort_score=0排在已回灌的高分游戏之后、未刷分组之首。
  • API 全绿 ≠ UI 通:编排器旁路会掩盖 UI 缺陷,用户可见波次收口前必须做一次真 UI 走查(见 ui-walkthrough-cdp.md)。

6. docker compose 部署到 mini-infra观测栈第一波实战蒸馏2026-07-05

观测栈五件Collector/Prometheus/Tempo/Loki/Grafana起在 mini-infra 时,从 compose 写好到五件全绿踩了四个坑,没一个是 compose 语法错——docker compose config 全过、pull 也成功,问题全在环境和镜像。起容器前按这四条自查,能省一整轮排障。

  • 端口要 ss -tlnp 查、别只信 docker psdocker ps --format 只列 bridge 网容器的端口映射host 网容器mini-infra 的 nacos/rocketmq 用 host 网)和宿主进程占的端口一个都不显示。观测栈 Prometheus 默认 9090恰好撞上 mini-infra 自己跑的 mihomoclash 内核§3 已记它占 9090 当 API 端口)——摸底时 docker ps 看不到、起容器才报 address already in use。起容器前对每个要对外映射的端口跑 ss -tlnp | grep :<port>撞了就让Prometheus 让到了 9091
  • 开了 -config.expand-env 的组件,配置注释里别写 ${...}。Loki、Tempo、OTel Collector 开 -config.expand-env 后,会把整个配置文件文本(连注释一起)拿去展开 ${VAR},而且校验严格:变量名里出现通配符(比如注释里图省事写 ${MINIO_*} 指代两个变量)就报 missing closing brace、容器起不来。注释写成纯文字「MINIO_ACCESS_KEY / MINIO_SECRET_KEY 两个变量」),别用 ${} 形式。这坑 Tempo 和 Loki 同款,别以为哪个展开器宽松(我第一次还误判 Tempo 宽松、又在修复注释里写了一遍反例 ${MINIO_*} 二次踩坑)。
  • pull 成功不等于 binary 在,起容器前 docker run --rm <img> --version 验一下。daocloud mirrormini-infra 的 registry-mirror缓存的 otel/opentelemetry-collector-contrib:0.116.0 是坏的——只有两层、缺主 binary起容器报 exec /otelcol-contrib: no such file or directorydocker rmi -f 后重新下载 layer、digest 不变、还是坏。这种坏 docker compose configpull 都发现不了。验法:docker run --rm <img> --version,输出版本号才算真好。坏了换邻近 tag0.116.0 坏、0.114.0 和 0.155.0 好0.115.0 mirror 直接 403
  • 换镜像 tag 要顺带复核配置字段兼容。上一条换 tag 时踩到:降到 collector 0.114.0 后redaction 处理器不认 blocked_key_patterns / redact_all_types(这俩是新版才加的字段),而脱敏是安全红线、砍了键名屏蔽不行,只能往上取 0.155.0(字段最全、向后兼容 0.116 配置)。换 tag 别只看 binary 起不起来,还要看这版本认不认你的配置字段。

部署落点与运维compose 源在仓 deploy/infra/observability/、部署位置 mini-infra:/opt/infra-observability/rsync 同步(.env 排除、服务器上 chmod 600 不入仓),docker compose up -dHOST=100.64.0.8 bash health-check.sh 五件全 200 = 绿。访问方式Grafana 口令/端口/MinIO 桶)见 docs/内网凭据与端点.md 观测栈段。ssh 连法同 §2ssh -o ProxyCommand=none root@100.64.0.8

7. 生成线cheap / tier2 Python service在 mini-desktop 的环境地图2026-07-05 波③ OTLP 真跑蒸馏,免重复探索)

生成线的 Python 服务(便宜档 cheap-worker、tier2 gen-worker跑在 mini-desktop布局与 huijing 后端两码事,摸底时几处岔路很吃时间。下面这些坐标都经波③ OTLP 真跑坐实,后续接生成线直接照用,别再从零翻找。

  • 真检出 = /root/games-development-ai/dev/2.0.0),不是 /root/tier2-run/。后者是一份陈旧检出(停在 c0135926、阶段二那批),里头同样有 cheap-worker/ 和 tier2/ 目录、极易误认,但它的 .venv 早已不在、跑不起来。认准 /root/games-development-ai/ 这份。
  • cheap-worker 用自己的 venv/root/games-development-ai/cheap-worker/.venv/bin/pythonuv 建,装了 agentscope + opentelemetry 的 SDK 与 OTLP/HTTP exportertier2 gen-worker 的 venv 在 /root/.venvs/agentscope-tier2/uv 本体在 /root/.local/bin/uv。系统默认 /usr/bin/python33.12)里 pip、agentscope、opentelemetry 一个都没有,别拿它跑生成线脚本。
  • 这份检出的 cheap-worker/ 带本地未提交改动,别盲 git pull / reset --hard 覆盖。mini-desktop 上 cheap_service_app.py / cheap_studio.py / cheap_service_driver.py / cheap_verify.py 有本地补丁(含 m3_stream_patch.py 的 M3 流式补丁),处于分叉状态。更新单个文件用 scp -o ProxyCommand=none <file> root@100.64.0.7:<path>(单文件传输分类器不拦,见 §2波③ 部署 cheap_otlp_sink.py 即用此法),或先 git stash 核对再动;直接覆盖会抹掉这些没进仓的补丁。
  • 生成线端口:便宜档 AgentScope Service :8300、便宜档 worker HTTP :9501、tier2 gen-worker :8200。用上面的 venv python 跑对应入口(cheap_service_app.py / worker_service.py)起服务,门参与预算从 Nacos100.64.0.8:8848、namespace 为空串)热读。
  • Python 侧跨机 / 出网必须绕本机 clash fake-ip198.18.x发往内网100.64.0.8 的 Collector :4318、new-api :3000 等)前设 NO_PROXY=100.64.0.8,localhost,127.0.0.1 并清 http_proxy / https_proxycurl 用 --noproxy '*')。便宜档 OTLP sink 已在建 exporter 前调 worker.client.install_proxy_bypass 幂等兜一层。跨机可达实证mini-desktop → mini-infra:4318 返 200。
  • 波③ OTLP span 真跑配方:设 CHEAP_OTLP_ENDPOINT=http://100.64.0.8:4318,用 cheap venv python 跑一局便宜档生成(或直接把 TraceStep 喂给 cheap_otlp_sink.make_cheap_otlp_sinkspan 会以 service.name=cheap-gen-worker 落 Tempo。查 Tempo 要等 ≥15sCollector tail_sampling decision_wait=10s 叠 Tempo ingestcurl -s --noproxy '*' -G http://100.64.0.8:3200/api/search --data-urlencode 'q={ resource.service.name="cheap-gen-worker" }'。注意采样口径——只有 error 状态的 span 必被采tail_sampling status_code 策略),正常 span 走 10% 概率采样、查不到是正常现象,真跑验证要用带 error verdict 的 step 才稳。
  • 观测栈自身还没被观测Prometheus 暂未 scrape Collector 的内部 telemetry容器内 :8888otelcol_receiver_accepted_spans_total 一类管道计数器在 Prometheus 里查不到(留波⑤ 补 collector self-scrape。要判断 span 到没到,直接查 Tempo别指望这些计数器。
  • tier2 源工程落库接后端W-ASSET-SRC T1 接线2026-07-05:让 tier2 富游戏的 src/ 产物从落本地盘改落 MySQL+MinIO 的开关 = tier2 gen-worker 起服时的环境变量 TIER2_STORE=backendworker/store.pydefault_store() 唯一读它,不设=回落 LocalFsStore 本地盘)。它落在 tier2 服务起栈 env 单点(与上面 :8200 venv 入口同处设,别在别处硬编码 BackendStore 类)。翻开关前先核两件底账,免一开就撞空库:① tier2 逻辑库要先在真 MySQL 建好,CREATE DATABASE IF NOT EXISTS tier2(对齐 infra.yaml mysql.database=tier2);② tier2_source_project_version 表的 status 列状态要确认——BackendStore._ensure_schema 首次 save 会 CREATE TABLE IF NOT EXISTS 并按 information_schema 探测缺列补跑 ALTER ADD COLUMN status,但若历史窗口已把这张表建成无 status 列的旧形态,确认它被 ALTER 补上(或确认无存量数据时 DROP 重建),处置记进接线日志。翻开关后先真跑一次「生成一款富游戏 → 收口落库」,确认日志出现 BackendStore.save 落库成功(committed) 而非 LocalFsStore 的落库行。回滚 = 起服 env 去掉该开关即整体回落 LocalFsStore,一处可逆、无数据迁移。取回重建的五条闭环由 scripts/store_roundtrip_harness.py --backend 在此真基建上验(本机 worktree 无真库 / 无 esbuild跑不了 bundle 字节相等,属本窗口 follow-up
  • tier2 孤儿清扫 jobW-ASSET-SRC T4manifest-first 把半落库残片变成可见的 pending 行后,超时未收尾的 pending 行连同其 MinIO 前缀对象由 scripts/store_cleanup_job.py 回收(乐观删 CAS 防与续 put 的 TOCTOU 竞态、幂等)。在此机用 tier2 同套 venv + TIER2_STORE=backendcron / systemd-timer 定时跑即可(如每小时 --ttl 3600owner = 生成线tier2。回收正确性已由 tests/test_store_backend_manifest_first.py 的内存 fake 用例坐实,真库真跑排本窗口。

8. 后端 → 生成线派发接线executor·内测 dev 闭环命脉2026-07-05 真 e2e 坐实)

huijing 后端把生成请求投给 Python 生成线,靠 aigc.executor 这组配置——它是内测核心闭环的命脉,却默认关闭。aigc.executor.enabled 缺省 false起栈时一旦漏注 AIGC_EXECUTOR_*executor 整组 BeanWorkerDispatchClient / GenTaskConsumer / @Scheduled tick@ConditionalOnProperty 挡在装配外生成请求入队成功却无人分派、永远跑不起来、且不报错。2026-07-05 起 dev 全栈正是栽在这:只注了 MYSQL/REDIS/NACOS 三口令、漏了 executor便宜档 create→generate 静默卡在 queued。

派发链路:submitGenerate 落库 queued → GenTaskProducer 发 RocketMQ → GenTaskConsumer CAS 认领 → WorkerDispatchClient POST job 到 worker-url → Python worker 生成 → 回调 /dify/callback-internal → 落版本 + 运行包;@Scheduled tick 兜底轮询 DB。

dev 正确配置固化在 /root/huijing-dev.envchmod 600、单一事实源/root/restart-huijing-dev.sh 从它 systemd-run 重建 transient unit huijing-dev。关键项:AIGC_EXECUTOR_ENABLED=true(装配整组,默认 false = 不分派)、AIGC_WORKER_URL=http://127.0.0.1:9501/generate(逐字节对齐 worker 的 DEFAULT_PORT=9501 + POST /generate)、AIGC_CALLBACK_SECRET=HMAC 验签关worker 侧 CALLBACK_SECRET 亦空 = 两端对齐,非空则两端必须逐字相同)、NEWAPI_KEY = api-key值见凭据档MiniMax 计费dispatcher 默认 http= WorkerDispatchClient,别开 saa 进程内旧路、dispatchTemplateId 默认 generic(见下)。

分派闸是硬相等 templateId=='generic'AigcGenerateExecutor.java:535-536):只有 templateId 恰等 generic 才投 worker其余business-sim 等旧模板名)一律 fall-through 到进程内 LLM 旧路、到不了 :9501。便宜档真实流一句话、不选模板= 草稿空 templateId → 后端归一 generic → 派 worker品类由 Python 层按 brief 文本判。冒烟 / e2e 必须用 generic别用 business-sim——它虽在 SUPPORTED_TEMPLATE_IDS 提交校验放行,却与分派闸解耦、会静默走旧路。

陈旧 /root/game-staging/infra/.env 别照搬:那套 AIGC_* 是 gamedef 时代的值(:9401 / dispatcher=saa / sourcemode=gamedef / gameruntimedir 指退役目录),与 M3 cutover 后的便宜档 Python 线不符,照搬即错。

交付边界:生成成功落的是 status=0 预览包(如 versionId 93151、bundle 243KBfeed 不显示;需运营在审核台 APPROVEstatus 0→1才进 feed。这是生成线与产品 / 审核轨的交界cutover plan §2.2),不是 bug。可逆/root/huijing-dev.envAIGC_EXECUTOR_ENABLED 改回 false 重跑 restart 脚本,即回到「入队不分派」的现行行为,一处开关、无数据迁移。

9. OTel Java agent 挂载阶段四观测·面一b2026-07-05 dev 真机坐实)

给 huijing 后端挂 OpenTelemetry Java agent = 一个参数拿全链 traceSpring MVC/JDBC/Redis/出网 HTTP 自动织入 span且出网时自动注入 traceparent顺带兑现面四的 Java→worker 那跳。dev 落法不改 restart 脚本硬编码的 java 行,靠 JAVA_TOOL_OPTIONS 注入:

  • agent jar = /root/otel/opentelemetry-javaagent.jar2.29.024MB。外网从 aliyun maven 镜像 --noproxy '*' 直连下:maven.aliyun.com/repository/public/io/opentelemetry/javaagent/opentelemetry-javaagent/2.29.0/opentelemetry-javaagent-2.29.0.jardev 的 ~/.m2/settings.xml 镜像 central→aliyun直连可达
  • /root/huijing-dev.env 追加一块(单一事实源,可逆=删块重启即回退JAVA_TOOL_OPTIONS=-javaagent:/root/otel/opentelemetry-javaagent.jar + OTEL_SERVICE_NAME=huijing-server + OTEL_EXPORTER_OTLP_ENDPOINT=http://100.64.0.8:4318mini-infra Collector在 no_proxy 内直连)+ OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf + OTEL_METRICS_EXPORTER=none + OTEL_LOGS_EXPORTER=nonemetrics 归面五 micrometer/prometheus、logs 后置agent 只发 traces 免重复)+ OTEL_TRACES_SAMPLER=parentbased_always_ondev 全采,尾采样交 Collector
  • 验:重启后启动日志 Picked up JAVA_TOOL_OPTIONS + opentelemetry-javaagent - version: 2.29.0启动加约 10s(织入开销,可接受);发几个请求后 Tempo GET /api/search/tag/service.name/valueshuijing-serverGET /api/search?tags=service.name%3Dhuijing-server 出真 tracePING/POST span。旁路风险兜底只读冒烟 12/12 全过、agent 无 OTLP 导出错误。

坑与注记:① 指标是进程内 micrometer重启即清零——Prometheus 抓的时序在 restart 处有 counter resetrate()/increase() 天然处理;单次 scrape 看不到累计值不是 bug排「gen_task_total 缺失」先想是不是刚重启过)。② watchdog 超时收尸stale RUNNING > 15min→failed(timeout)确经 handleCallback 唯一写入路径→面五埋点会计 timed_outdev 实证 task206 走此路);迟到的重复 worker 回调在 handleCallbackTx 抛 AIGC_CALLBACK_TASK_FINAL 拒绝重入、先于 postCommitBestEffort故不重计。③ 便宜档需续修的 gen 延迟可达 20mintask206初生成 + H_progress 门未过续修 + 等远程 LLM → 最终 15min watchdog 阈值收尸 failed(timeout)gen_duration 埋点正为量化这条内测 UX 关注线。