Merge pull request 'log DirectProject 审批拒绝原因' (#566) from fix/log-cmd-refuse-reason into master
Project CI / AI game creator shell Rust crates (push) Successful in 1m36s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m15s
Project CI / Backend tests (push) Successful in 4m12s
Project CI / Frontend tests (push) Successful in 1m52s
Project CI / Native shell tests (push) Successful in 6m21s
Project CI / Repository checks (push) Successful in 2m25s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 10m12s
Project CI / AI game creator shell web tests (push) Successful in 1m50s
Project CI / AI game creator shell Rust lane 1/2 (push) Failing after 12m6s

Reviewed-on: #566
This commit was merged in pull request #566.
This commit is contained in:
2026-10-01 17:01:21 +08:00
3 changed files with 352 additions and 112 deletions
File diff suppressed because it is too large Load Diff
@@ -18,7 +18,7 @@ mod execution;
mod model_catalog;
pub(crate) use direct_project_identity::thread_id_for_project;
use direct_project_identity::*;
use execution::ExecutionAdapter;
use execution::{ExecutionAdapter, ResponseDeliveryFailure};
const GAME_CREATOR_CODEX_APP_SERVER_PROVIDER_ID: &str = "genarrative_agc";
const GAME_CREATOR_CODEX_APP_SERVER_API_KEY_ENV: &str = "GENARRATIVE_AGC_CODEX_API_KEY";
@@ -4824,7 +4824,7 @@ async fn read_game_creator_codex_app_server_stdout(
};
if !sent {
if let Some(adapter) = adapter {
adapter.response_write_failed();
adapter.response_delivery_failed(ResponseDeliveryFailure::Write);
}
}
});
@@ -4856,7 +4856,9 @@ async fn read_game_creator_codex_app_server_stdout(
let adapter = inner.execution.lock().ok().and_then(|slot| slot.clone());
if let Some(adapter) = adapter {
if !adapter.bind_turn(turn_id) {
adapter.response_write_failed();
adapter.response_delivery_failed(
ResponseDeliveryFailure::TurnBindMismatch,
);
}
}
}
@@ -1,5 +1,13 @@
# 决策记录
## 2026-10-01 DirectProject 审批拒绝原因留痕
- 决策:宿主拒绝 app-server 的审批 / 交互请求时,原因必须落 AppData `RUST` 日志。稳定键 `agent.direct_codex.approval.denied`,字段为 `thread_id` / `method` / `reason` / `distinct_reasons`;未绑定宿主执行器时另记 `agent.direct_codex.interaction.no_adapter`(`method` / `outcome`,`outcome` 区分 `decline` / `empty-permissions` / `unsupported-method`);回包未送达另记 `agent.direct_codex.approval.response_delivery_failed`,`cause` 区分 `response-write-failed` 与 `turn-bind-mismatch`。
- 原因:线上对审批只回 `{"decision":"decline"}`,模型与用户都看不到是哪一道闸门(合同缺失 / 预算耗尽 / 阶段已收束 / item 不在途 / 无适配器)拦下的,只能靠复现。
- 边界:`reason` 只接受 `execution.rs` 内的静态分类或宿主自己的错误文本;透传的宿主错误在留痕出口统一走 `sanitize_diagnostic_message`,不带请求参数、上游正文、路径或凭据(去重键也用脱敏后的文本)。有界去重一律按 `MAX_DENIED_REASON_LOGS = 64` 条封顶——适配器路径按回合内 `(method, reason)`、未绑定执行器路径按进程级 `(method, outcome)`、回包未送达按回合内原因各只记一次。拒绝留痕在释放审批临界区(`state`)之后进行;回合收束说明按 `cause` 区分,只有 `response-write-failed` 才说「回包丢失」,`turn-bind-mismatch` 说明作用域无法确认。
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/execution.rs`。
- 验证:`cargo test --bin genarrative-ai-game-creator-shell agent::codex_app_server::execution::tests`(15 passed,含 `denied_approval_records_its_reason_once_per_turn`、`denied_reason_logging_is_bounded`)、`npm run check:encoding`、`git diff --check`。
## 2026-09-30 退役 DirectProject 工具调用与回合流账本(issue #553)
- 背景:`tool-calls.jsonl` / `turn-stream.jsonl` 是只写不读的账本——读命令在 2026-09-16 随聊天真相源收敛删除后,唯一"消费方"是 `game-creator-direct-turn-update` 事件,而全仓已无监听方;工具卡片的真实读路径早已是「项目对话历史 + 运行态事件」的前端投影。issue #553 还暴露了同一时期绝对路径脱敏误伤 HTML 结束标签的问题。