内存里的工具观察保持原文,落盘那份按存储口径脱敏
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m10s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m1s
Project CI / Frontend tests (pull_request) Successful in 2m16s
Project CI / Repository checks (pull_request) Failing after 13s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Failing after 5m57s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m10s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Failing after 8m6s
Project CI / Native shell tests (pull_request) Successful in 6m36s

- `build_game_creator_agent_runtime_pending_tool_action` 在嵌入 observations 前按存储口径脱敏:pending ledger 受 fail-closed 门禁保护,工具原文里的项目绝对路径会让整次持久化被拒
- `runtime_driver/main_loop`、`runtime_state` 的过期续跑、`runtime_actions/parallel_read` 不再把脱敏结果写回内存观察向量,prompt 继续用原文
- `parallel_read` 的前缀核对仍用脱敏投影比较,只是不再覆盖内存向量
- 持久化侧(context bundle / pending action)自己脱敏,内存与落盘两份从此解耦
This commit is contained in:
2026-10-02 10:56:32 +08:00
parent 7224bd0dc0
commit 3d68d56524
4 changed files with 7 additions and 12 deletions
@@ -717,7 +717,6 @@ pub(in crate::agent) fn project_game_creator_agent_runtime_parallel_read_batch(
));
}
}
*observations = stored_observations;
let mut runtime_projected_count = 0_usize;
let mut missing_projection_seen = false;
@@ -892,10 +891,6 @@ pub(in crate::agent) fn project_game_creator_agent_runtime_parallel_read_batch(
if !already_projected_to_context {
context_tracker.record(&observation);
observations.push(observation);
*observations = sanitize_game_creator_agent_runtime_context_observations_for_storage(
root,
observations,
);
persist_game_creator_agent_runtime_context(
root,
runtime,
@@ -267,7 +267,12 @@ pub(in crate::agent) fn build_game_creator_agent_runtime_pending_tool_action(
.map(|item| sanitize_agent_runtime_text(item, 180))
.collect(),
fallback_response: sanitize_agent_runtime_text(&plan.response, 1_200),
observations: observations.to_vec(),
// pending action 是 fail-closed 门禁保护的 durable ledger:嵌进去的观察必须先按存储口径
// 脱敏,否则工具输出里的绝对路径会让整次持久化被拒。给模型看的那份 observation 不受影响。
observations: sanitize_game_creator_agent_runtime_context_observations_for_storage(
root,
observations,
),
project_revision_before: project_revision_before.clone(),
verification_gate_before: read_game_creator_agent_runtime_verification_gate(
root,
@@ -1810,10 +1810,7 @@ async fn run_game_creator_agent_background_task_pass_without_deadline(
final_reply_revision = Some(planning_request_revision.revision);
}
}
observations = sanitize_game_creator_agent_runtime_context_observations_for_storage(
&root,
&observations,
);
// prompt 用的是内存里的原文;落盘那份由持久化自己按存储口径脱敏。
let _ = context_tracker.complete_loop(loop_index + 1);
if let Err(error) = persist_game_creator_agent_runtime_context(
&root,
@@ -998,8 +998,6 @@ pub(crate) fn prepare_game_creator_agent_background_stale_continuation_at(
plan.response.clear();
context_tracker.record(&blocker);
observations.push(blocker);
*observations =
sanitize_game_creator_agent_runtime_context_observations_for_storage(root, observations);
let next_loop_index = usize::try_from(state.loop_iteration).unwrap_or(usize::MAX);
persist_game_creator_agent_runtime_context(
root,