From 51c4174b73b0e1d3e291d5d510e384914d00d712 Mon Sep 17 00:00:00 2001 From: Linghong Date: Wed, 16 Sep 2026 05:10:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20AGC=20Rust=20shard=204=20?= =?UTF-8?q?=E7=9A=84=E4=B8=A4=E4=B8=AA=20CI=20=E5=A4=B1=E8=B4=A5=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - direct_registered_taonier_runtime_image_paths 通用平台图兜底补齐 canonical 切片排除:assets/art-spritesheet-slices/ 下的切片只经完整 manifest/receipt/内容校验放行,内容被篡改的切片不再绕过完成门禁 - direct_completion_scans_npm_scene_modules 测试改为保留 fixture 有效切片,不再依赖被修复的兜底漏洞 - mixed_project_history_rows 过时测试按 d48d09905 收紧后的契约改为断言 DirectProject 链对 legacy 行失败关闭 --- .../src-tauri/src/agent/direct_runtime/mod.rs | 14 ++++++++----- .../src/project/conversation/tests.rs | 21 +++++++------------ 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs index 7f743d89b..f0e482126 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs @@ -2555,6 +2555,15 @@ fn direct_registered_taonier_runtime_image_paths(root: &Path) -> Vec { .generation_route .as_deref() .is_some_and(|route| route.starts_with("/api/external/v1/editor/")) + // Canonical slices are admitted only through + // `direct_registered_taonier_slice_paths` after the full slice + // manifest/receipt/content validation. This generic fallback + // must not re-admit a slice whose bytes no longer match the + // registered receipt. + && !(asset.kind == "art-spritesheet-slice" + && asset + .local_path + .starts_with("assets/art-spritesheet-slices/")) }) .filter_map(|asset| { let path = direct_normalized_project_asset_path(&asset.local_path)?; @@ -8220,11 +8229,6 @@ mod tests { "const player = new Image(); player.src = '/assets/art-spritesheet-slices/player.png';", ) .expect("scene"); - std::fs::write( - root.join("assets/art-spritesheet-slices/player.png"), - tiny_opaque_png(), - ) - .expect("slice"); assert_eq!( direct_game_sources_referenced_taonier_assets(&root), diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/conversation/tests.rs b/apps/ai-game-creator-shell/src-tauri/src/project/conversation/tests.rs index 9bad4a007..993c1c378 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/conversation/tests.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/conversation/tests.rs @@ -272,7 +272,7 @@ fn project_history_skips_direct_project_rows_but_keeps_other_broken_rows_failing } #[test] -fn mixed_project_history_rows_stay_readable_from_both_sides() { +fn mixed_project_history_rows_read_by_generic_chain_but_fail_closed_for_direct_project() { let root = unique_conversation_test_root(); init_local_game_project_at(&root, "project-1", "写侧统一测试").expect("init project"); write_project_history(&root, &[DIRECT_PROJECT_ROW]); @@ -309,19 +309,12 @@ fn mixed_project_history_rows_stay_readable_from_both_sides() { vec!["模式切换后由通用写入器补写的回复", "带 id 的旧格式回复"] ); - // 反向:DirectProject 链把同一份文件里的两种行都读出来,混合文件不构成毒化。 - let direct_items = crate::agent::read_direct_project_history_items_at(&root) - .expect("DirectProject must keep reading the mixed history"); - assert_eq!( - direct_items - .iter() - .map(|item| item["content"][0]["text"].as_str().unwrap_or_default()) - .collect::>(), - vec![ - "再加一个按钮", - "模式切换后由通用写入器补写的回复", - "带 id 的旧格式回复", - ] + // 反向:DirectProject 链只接受 response_item 信封,混合文件里的 legacy 行让它失败关闭。 + let error = crate::agent::read_direct_project_history_items_at(&root) + .expect_err("DirectProject must fail closed on legacy rows"); + assert!( + error.starts_with("DirectProject 历史记录类型无效"), + "{error}" ); std::fs::remove_dir_all(root).ok();