From a09a03e91e195b147448427fcabe6a2a2df6ebc7 Mon Sep 17 00:00:00 2001 From: zizi Date: Wed, 17 Jun 2026 02:06:31 +0000 Subject: [PATCH] =?UTF-8?q?docs(round3):=20SAA=E8=B7=AFtrace=E6=8E=A5?= =?UTF-8?q?=E7=BA=BFsplit-brain=E7=9C=9F=E5=BA=93=E6=94=B6=E5=8F=A3?= =?UTF-8?q?=E2=80=94=E2=80=94verdict=E8=90=BD=E6=A1=A3+saa-graph=C2=A76?= =?UTF-8?q?=E8=92=B8=E9=A6=8F+=5Findex=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - verdict: dispatcher=saa+trace.enabled=true真库验trace_json非空/readiness=74,开关关NULL(additive字节零变),进程内非HTTP非HMAC,live未动 - saa-graph§6: 新增「多派发路·回调可观测字段必须每路都set」铁律(回调trace split-brain,与发布裁决split-brain区分)+字节兼容红线+readiness浮动/firstPlay quirk坑 - _index: SAA段注册execution+verdict为已收口,登记F5/F3/早期boot预热follow-up Co-Authored-By: Claude Opus 4.8 (1M context) --- .agents/skills/saa-graph-orchestration.md | 1 + ...3-SAA-trace-split-brain-real-db-verdict.md | 88 +++++++++++++++++++ docs/agent-specs/_index.md | 1 + 3 files changed, 90 insertions(+) create mode 100644 docs/agent-specs/2026-06-17-round3-SAA-trace-split-brain-real-db-verdict.md diff --git a/.agents/skills/saa-graph-orchestration.md b/.agents/skills/saa-graph-orchestration.md index 3c53120d..af3c2fce 100644 --- a/.agents/skills/saa-graph-orchestration.md +++ b/.agents/skills/saa-graph-orchestration.md @@ -69,6 +69,7 @@ SaverConfig sc = SaverConfig.builder().register(saver).build(); - `GenerationDispatcher.dispatch(job)` 接口 → 两实现 `WorkerDispatchClient`(http) | `SaaGraphDispatcher`(进程内 SAA 图) 经 `aigc.executor.dispatcher`(默认 **http** 非破坏) 二选一**单写**。 - `SaaGraphDispatcher`:job→state→后台单线程 `compiledGraph.invoke(threadId=traceId)`→出口组 `DifyCallbackReqVO` **进程内直调 `difyCallbackService.handleCallback`**(消灭 HTTP+HMAC,复用唯一三表同事务写链);串行真玩门 `Semaphore(1)` 守端口;图执行不包大事务(落库走 handleCallback 内短事务);失败统一归 `llm_error`(图内真因不在契约#6 七值枚举内)。 +- 🔴 **铁律「多派发路·回调可观测字段必须每路都 set」(回调 trace split-brain,与下方发布裁决 split-brain 是两回事)**:存在多条派发路(http worker / SAA 进程内 / executor 旧路)时,任一落库可观测字段(`trace_json`/`readiness_score`)若只在部分回调构造点 set,换 `dispatcher` 即**静默丢字段**。实证:`SaaGraphDispatcher.buildCallbackReqVO` 原只 set status/engineBundle/failureReason、**漏 setTrace** → `dispatcher=saa`(未来主力路)时 `trace_json` 恒 NULL、组B 9d/D11/D9 在 SAA 路静默失效(HTTP 路因 worker `_extract_trace` 不漏)。**修法**:派发器回调构造点**对称镜像** worker 的 `_extract_trace`——从图终态 `OverAllState` 抽与之**字节兼容**的 camelCase 子集 `setTrace`,严格 additive + best-effort(整段 try-catch 返 null,抽不到绝不打断生成)+ 复用同一 `aigc.trace.enabled` flag,落库走现成 `persistTraceQuietly`,零改契约/消费侧。**字节兼容红线**:抽出键集必须=worker `_extract_trace` camelCase 子集(`stage_fail→stageFail` 等 snake→camel;attempts **不含 per-attempt guards**——SAA 源端三处 appendAttempt 从不写,照 K_ATTEMPTS 注释抽会逼实现造假;readiness 读**顶层** `sevenGateVerdict.guards.H_progress` 而非 attempts[].guards),否则审核台/D11 两路读不一致。闭合:Round3 `703e462c`(HJ-AGI-002 线),真库验 task141 `trace_json` 真非空/readiness=74、task145(开关关)NULL(verdict `2026-06-17-round3-SAA-trace-split-brain-real-db-verdict.md`)。坑:readiness 真值随真跑质量浮动(repairs=5→stability 降、cost 缺→efficiency 中性,故 74 类型:staging 真库端到端验收(坐实 split-brain 已闭合)。 +> 结论:**split-brain 真库已闭合 ✅**——`dispatcher=saa` 进程内派发路真跑生成后 `trace_json` 真非空、`readiness_score` 真有值;`aigc.trace.enabled=false` 时同路 `trace_json` 真 NULL(修前行为字节零变)。 +> 执行环境:mini-desktop(100.64.0.7)x86 权威机隔离实例 `:48090`;连 staging 隔离 MySQL `ruoyi-vue-pro@127.0.0.1:13306`(容器 `game-staging-mysql`);**live `:48080` 全程未动**(pid 479414 不变,启动 Jun16 20:24,验收全程 uptime 持续增长无重启,health/feed/admin 全程 200)。 +> 构建源:origin/dev/2.0.0 `aff886d1`(含修复 commit `703e462c`),mini-desktop `/root/build-lane-s` 同步构建。 +> 时间:2026-06-17 09:18~10:00(CST)。 + +--- + +## 0. 结论先行 + +| 验证项 | 结论 | 关键证据 | +|---|---|---| +| **修复在可跑产物** | ✅ | `javap` 实证 `game-module-aigc-server.jar`(09:19 重建,嵌入 huijing-server.jar BOOT-INF/lib)含 `extractTraceQuietly(OverAllState,Map,String,long)` + `TRACE_MAPPER` 字段 + `buildCallbackReqVO(...,long wallMs)`(签名改)。 | +| **trace.enabled=true 真库(核心断言)** | ✅ **PASS** | task 141(dispatcher=saa 进程内回调)真库行:`status=2`、`trace_json IS NOT NULL`、`readiness_score=74`、`pass=true`、`wallS=679.993`、`attempts=7 条`、`sevenGateVerdict.guards` 非空(含 9 门键 H_progress 等)、`gameId="saa-aigc-944d…"`、`stage="saa"`、versionId=93114。 | +| **trace.enabled=false additive(字节零变)** | ✅ **PASS** | task 145(**同 saa-graph-dispatcher 进程内回调路**,真跑九门 succeeded)真库行:`status=2`、`trace_json IS NULL`、`readiness_score NULL`、versionId=93115。后端日志该 task **无 `[persistTrace]` 行**(persistTraceQuietly :254 守卫旁路)。 | +| **进程内路·非 HTTP·非 HMAC** | ✅ | 两 task 回调线程均 `saa-graph-dispatcher-1`;`图执行完成,进程内回调`→`handleCallback`→三表写链同线程;该 traceId 全程无 `/dify/callback-internal` 出站、无 HMAC 验签。 | +| **键集字节兼容 `_extract_trace`** | ✅ | task 141 顶层键 `[pass,stage,wallS,gameId,models,player,tokens,repairs,attempts,gatespec,sevenGateVerdict]`(camelCase);attempts 全 camelCase、零 snake_case 泄漏;`similarity` 键正确缺省(D9 未接 SAA,符合 spec §2.2);readiness 五读点 `pass`/`gatespec.driver`/`sevenGateVerdict.guards.H_progress`/`repairs` 真连通(cost.totalRmb 缺省→efficiency 中性,readiness=74 即此故低于 HTTP 路 96)。 | + +**一句话**:同一进程内 SAA 回调路,trace.enabled=true → trace_json 真落(split-brain 闭合)、=false → trace_json 真 NULL(additive 字节零变),**两向真库实证 = split-brain 已闭合**。 + +--- + +## 1. trace.enabled=true 真库行(核心断言·task 141) + +触发:form① 一句话生成(打砖块),gameId 9319,traceId `aigc-944d032b63574b0b85df9b2cbb19f6bc`;SAA 图 design→generate(M2.7+deepseek-v4-flash)→esbuild→九门 harness 真玩→repair×5→九门全过 succeeded(wall=679s)。 + +``` +-- 后端日志(线程 saa-graph-dispatcher-1,进程内): +09:37:45.620 [saa-dispatch] 图执行完成,进程内回调 status=succeeded, engineBundleLen=212861, wall=679993ms +09:37:45.620 [handleCallback] 收到 Dify 回调 status=succeeded(同线程,非 http-nio) +09:37:45.645 [createForPackage] 落包建版本成功 versionId=93114 +09:37:45.702 [handleCallbackTx] 落包完成 checksum=9bf8035c… bundleSize=217074 +09:37:45.714 [persistTrace] 落 trace_json + readiness_score 完成(非阻断)taskId=141, traceLen=3052, readiness=74 ← 修复点真触发 + +-- 真库行(game_aigc_task id=141): +status=2 has_trace=1 readiness_score=74 +pass=true wallS=679.993 n_attempts=7 has_guards=1 repairs=5 +gameId="saa-aigc-944d032b…" stage="saa" version_id=93114 trace_len=3833 +顶层键集=[pass,stage,wallS,gameId,models,player,tokens,repairs,attempts,gatespec,sevenGateVerdict] +sevenGateVerdict.guards 键=[A_boot,B_uncaught,C_frame,D_render,E_live,F_wiring,G_input,H_progress,I_control] +gatespec.driver={"type":"paddle-intercept","paddleY":830,"ballPath":"ball.x"}(readiness 读点真连通) +attempts: 角色 design/code/fix×5;usage.{in,out} 子集真在;零 stage_fail(snake) 泄漏 +``` + +- 无 `trace 抽取失败` warn → `extractTraceQuietly` 成功;无 `/dify/callback-internal`、无 HMAC(进程内路)。 + +## 2. trace.enabled=false additive 行(task 145) + +重启隔离实例 `-Daigc.trace.enabled=false`(`-Daigc.executor.dispatcher=saa` 不变,ExecStart 实证);触发同款生成,gameId 9324,traceId `aigc-a15d001e…`;SAA 图真跑九门→repair→succeeded(wall=443s)。 + +``` +-- 后端日志(同 saa-graph-dispatcher-1 进程内回调路): +09:58:15.664 [saa-dispatch] 图执行完成,进程内回调 status=succeeded, engineBundleLen=211977 +09:58:15.664 [handleCallback] 收到回调 status=succeeded(同线程) +09:58:15.691 [handleCallbackTx] 建版本完成 versionId=93115 +09:58:15.740 [handleCallbackTx] 落包完成 checksum=3bcf90b1… bundleSize=216119 +09:58:15.746 [handleCallbackTx] 回调 succeeded 三表写入链完成 + ↑ 无 [persistTrace] 行——trace.enabled=false → persistTraceQuietly 守卫旁路 + +-- 真库行(game_aigc_task id=145): +status=2 has_trace=0(trace_json NULL) readiness_score=NULL version_id=93115 failure_reason=空 +``` + +**判据**:task 145 走的是与 task 141 **逐字相同的进程内 SAA 回调路**(同线程、同 handleCallback、同三表写链、同样真跑九门 succeeded),唯一差别是 `aigc.trace.enabled` 开关——trace_json 从「非空 11 键」翻为「NULL」,证修复**严格 additive,开关关=修前字节零变**。 + +## 3. 真库断言对照表 + +| id | dispatcher | trace.enabled | status | has_trace | readiness | pass | wallS | n_att | has_guards | version | +|----|-----------|---------------|--------|-----------|-----------|------|-------|-------|-----------|---------| +| 141 | saa | **true** | 2 | **1** | **74** | true | 679.993 | 7 | **1** | 93114 | +| 145 | saa | **false** | 2 | **0** | **NULL** | NULL | NULL | NULL | **0** | 93115 | + +## 4. 验收期揪出(环境侧,非修复缺陷) + +- **早期 boot SAA fast-fail 复现(Round2 §7-2 同签名)**:隔离实例重启后首 2~3 个 dispatch fast-fail(llm_error,无 saa-dispatch/图构造日志,task 0→3),第 4 个起稳态成功(task 145 真跑九门 succeeded)。= Round2 已登记的早期冷启瞬态(`ensureGraph`/图缓存未热 race),**与 trace 修复无关**(fast-fail 走 executor.callbackFailed 旁路,根本不触 buildCallbackReqVO)。生产 dispatcher=saa 重启后仍可能偶发,建议 dispatch 加 boot 预热/重试(沿 Round2 §7-2 待办)。 +- **GP9 并发门正确**:孤儿 RUNNING 任务(fast-fail 残留或被外部停的在飞任务)占满 per-creator 在飞=1 上限 → 新任务被 `控制平面 门①并发位满 → 拒`(code=1101001001),= 设计内正确门控,非缺陷。验收时手动 cancel 孤儿任务 142 释放并发位后续跑。 +- **systemd 后台线程日志(Round2 §7-3)**:早期 fast-fail 窗口 `scheduling-1`/dispatch 错误日志疑被吞(用 shell `> file` 重定向仍偶发);稳态后 scheduling-1 + saa-graph-dispatcher 日志均正常落。DB 状态为权威判据(不依赖日志)。 + +## 5. 证据 / 隔离实例清理 + +- 证据日志:mini-desktop `/root/round3-saa-true.log`(task 141 全链 + persistTrace 行)、`/root/round3-saa-false.log`(task 145 全链 + 无 persistTrace 行)、`/root/round3-e2e-*.out`。 +- 构建:`/root/build-lane-s`(HEAD aff886d1,含 703e462c);jar `game-cloud/huijing-server/target/huijing-server.jar`(09:19)。 +- 启动器:`/root/launch-round3-saa.sh`(密钥 NEWAPI_KEY/MYSQL_ROOT_PASSWORD/REDIS_PASSWORD 从 live 进程 environ 注入子 JVM,绝不打印/入命令行);断言器 `/root/round3-assert.sh`(MySQL `--defaults-extra-file`,禁明文密码)。 +- **清理**:隔离实例 `:48090` 已停(无 java 进程、无 systemd 单元、48090 不监听);harness 孤儿(e2e/serve-and-play/play.cdp/chrome)已清;**live :48080 未动**(pid 479414,feed/admin 200)。生成入隔离同库的草稿/任务/版本(9319/9324 等)入同库不污染 live 运行态(feed 过滤未发布)。 + +> 验证状态:trace=true 真库(含键集/guards/readiness 五读点)/ trace=false additive NULL / 进程内非 HTTP 非 HMAC / 修复在可跑 jar = **均带真库行 + 日志实证 + javap,全 PASS**。split-brain **真库已闭合**。 diff --git a/docs/agent-specs/_index.md b/docs/agent-specs/_index.md index aad275ca..5591aef5 100644 --- a/docs/agent-specs/_index.md +++ b/docs/agent-specs/_index.md @@ -18,6 +18,7 @@ ### agentic 基建(当前主线 HJ-AGI-002 = SAA-only) - `2026-06-15-SAA-AgentScope-agent平台-目标架构-review.md` — 当前 agentic 编排目标架构(决策口径) - `2026-06-15-SAA-能力API接入-dossier.md` — SAA API / 坑 源码权威档(落地照此) +- `2026-06-17-组B-SAA路trace接线-execution.md` + `2026-06-17-round3-SAA-trace-split-brain-real-db-verdict.md` — **已收口**:SAA 路回调 trace 观测 split-brain 闭合(`703e462c` 已落+真库验:dispatcher=saa `trace_json` 真非空/开关关 NULL;组B 9d/D11/D9 可观测在 SAA 主力路生效)。遗留 follow-up:F5=组B `ReadinessScorer` H_progress-asBool 既存 bug、F3=SAA cost 折¥、早期 boot SAA fast-fail 预热(Round2 §7-2) ### 引擎 / Runner v2(线已收口,留 SoT + 全弧顶层) - `2026-06-11-T1引擎终裁包.md` — Tier1=LittleJS 选型 SoT(含复议权 §4.5)