回退 sandbox 启动失败诊断日志,恢复 application.log 默认脱敏

- 回退 6311bb583:移除 sandbox 启动失败时采集子进程 stdout/stderr 的宿主日志及保留绝对路径的变体;
- application.log 恢复对所有行统一脱敏绝对路径的既有行为;
- 真实 npm 启动故障改从宿主 Node 环境修复,不改日志代码。
This commit is contained in:
2026-10-06 15:41:58 +08:00
parent 6311bb5837
commit eccaa5f79c
3 changed files with 7 additions and 176 deletions
@@ -4149,14 +4149,6 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
- 验证:并发执行全部 project verification 测试;同时真实运行 bwrap staged marker 用例,确认 child-created、block、ready、commit、exec 和目标退出链均稳定,目标 argv/env/FD 不含 nonce 或控制 socket。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/command_sandbox_trampoline.rs`、`command_sandbox.rs`、`command_exec.rs`、`project.rs`。
## sandbox 启动失败不能把子进程 stderr 一起丢掉
- 现象:`command.exec` 在 `wait_sandbox_ready` 阶段失败时,模型和日志只看到 `等待 command sandbox ready 失败:Connection reset by peer (os error 104)`;无法判断是 userns、AppArmor、mount 还是 trampoline 自身失败,真实 bwrap 报错完全不可见。
- 原因:bwrap/trampoline 以 `Stdio::piped()` 启动,但启动失败路径只调用 `terminate_project_command_process_group`(`kill` + `wait`)后即返回;`Child` 被回收时管道里的 stderr/stdout 一并丢失。项目自己的真实 launcher 测试(`command_sandbox.rs` 的 opt-in staged gate 用例)反而会 `wait_with_output()` 并把 stderr 打进 panic。
- 处理:启动失败统一走 `terminate_project_command_launch_and_log_diagnostics`:先 `take()` stdout/stderr,再 kill + wait,然后在有界时间(2s)和字节(8 KiB/流)内读空,经 `sanitize_diagnostic_message_preserving_paths` 只做凭据脱敏、保留绝对路径(bwrap 的 `Can't find source path` 里路径就是唯一证据),写入宿主 `application.log`;诊断只进宿主诊断包,不进入模型可见错误、command log、receipt 或 Agent DB。默认的 `sanitize_diagnostic_message` 仍然整行脱敏绝对路径,只有这条宿主失败日志走保留路径的变体。
- 验证:`sandbox_launch_diagnostics_keep_source_paths_and_redact_secrets` 断言源路径保留、凭据整体脱敏、纯空白流不产出行;`GENARRATIVE_COMMAND_SANDBOX_REAL_TEST=1 cargo test ... real_linux_opt_in` 的真实 bwrap 握手用例保持通过。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/command_exec.rs`、`command_sandbox.rs`、`command_sandbox_trampoline.rs`。
## bwrap 的命令分隔符不能从目标 argv 末尾反查
- 现象:普通命令握手正常,但 `cargo test -- --nocapture`、npm forwarded args 等包含独立 `--` 的合法目标参数可能在 sandbox preflight 或 staged launch 期间提前执行原目标。