Skip to content

Commit 9208b43

Browse files
committed
补齐 Rust WASM 首次任务的原生确认与修复闭环
1 parent e0e0f8a commit 9208b43

22 files changed

Lines changed: 1939 additions & 284 deletions

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,4 +813,6 @@ Rust edit feedback now reports safe lines, stable tasks and original Rustfmt rec
813813

814814
Rust edit dialogue now provides an executable post-batch Clippy command and explicitly states that project lint did not run during editing. Original-task repair-ready retains current rule/line feedback and withdraws changed-input guidance; this is not a background queue or authoritative closure. See [project lint follow-up](docs/Rust-Project-Lint-Followup.md).
815815

816-
Native-first Rust syntax tasks now have a scoped protected-host SDK resolution and same-tool recurrence path, binding the original counterexample and Cargo edition provenance. Production host approval integration and WASM-first Rust resolution remain pending; this does not qualify Clippy or project delivery. See [scoped acceptance](tests/acceptance/rust-task-resolution.md).
816+
Native-first and WASM-first Rust syntax tasks now share a protected-host SDK confirmation, scoped resolution and same-tool recurrence path. Native-first policy1.7/evidence0.8 retain grammar=null; WASM-first policy1.8/evidence0.9 retain the original grammar digest. Both bind the original counterexample and approved Cargo edition provenance; a native counterexample requests investigation, and incomplete or changed inputs cannot resolve. Production host approval integration remains pending; this does not qualify Clippy or project delivery. See [scoped acceptance](tests/acceptance/rust-task-resolution.md).
817+
818+
See [WASM-first acceptance](tests/acceptance/rust-wasm-task-resolution.md) for the actual execution path, protocols and counterexample routing.

‎README.zh-CN.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,4 +796,6 @@ Rust编辑反馈现保留安全行号、稳定任务与原Rustfmt复检指引,
796796

797797
Rust编辑后现提供可执行的批次后Clippy指令,明确编辑阶段未运行项目lint。原任务repair_ready保留当前规则/行号并撤回输入变化后的指引;这不是后台队列或可信关闭。见[项目lint后续流程](docs/Rust-Project-Lint-Followup.zh_CN.md)。
798798

799-
Rust 原生首次语法任务现有受保护宿主 SDK 关闭与同工具复发重开路径;固定 Cargo edition 来源与原反例,未完成或输入变化不能关闭。生产宿主批准接线和 WASM 首次任务仍待完成,不能替代 Clippy/项目门禁。详见 [限定验收](tests/acceptance/rust-task-resolution.md)。
799+
Rust 原生首次与 WASM 首次语法任务均可通过同一受保护宿主 SDK 确认、限定关闭和同工具复发重开。原生首次保留 grammar=null(策略1.7/证据0.8);WASM 首次保留真实 grammar 摘要(策略1.8/证据0.9)。两者绑定 Cargo edition 来源与原反例;原生反证转调查,未完成或输入变化不能关闭。生产宿主批准接线仍待完成,不替代 Clippy/项目门禁。详见 [限定验收](tests/acceptance/rust-task-resolution.md)。
800+
801+
WASM 首次闭环的实际执行路径、协议与误报分流见 [验收记录](tests/acceptance/rust-wasm-task-resolution.md)。

‎crates/codeguard-cli/src/task_lifecycle_store.rs‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub(crate) fn load(
8888
| "0.6.0"
8989
| "0.7.0"
9090
| "0.8.0"
91+
| "0.9.0"
9192
)
9293
) || value["report_type"] != "task_resolution_evidence"
9394
|| value["identity"] != identity_value
@@ -208,10 +209,16 @@ fn origin_matches_evidence(original: &serde_json::Value, evidence: &serde_json::
208209
| (Some("swift"), Some("0.3.0"))
209210
| (Some("kotlin"), Some("0.4.0"))
210211
| (Some("go"), Some("0.7.0"))
211-
| (Some("rust"), Some("0.8.0"))
212+
| (Some("rust"), Some("0.8.0" | "0.9.0"))
212213
) {
213214
return false;
214215
}
216+
if evidence["schema_version"] == "0.9.0"
217+
&& (!matches!(original["schema_version"].as_str(), Some("0.1.0" | "0.7.0"))
218+
|| !original["native_evidence"].is_null())
219+
{
220+
return false;
221+
}
215222
if evidence["schema_version"] == "0.8.0"
216223
&& (original["schema_version"] != "0.12.0"
217224
|| evidence["edition_context"]
@@ -400,9 +407,9 @@ pub(crate) fn record_native_recurrence(
400407
| (Some("0.3.0"), Some("swift"))
401408
| (Some("0.4.0"), Some("kotlin"))
402409
| (Some("0.7.0"), Some("go"))
403-
| (Some("0.8.0"), Some("rust"))
410+
| (Some("0.8.0" | "0.9.0"), Some("rust"))
404411
)
405-
|| (evidence["schema_version"] == "0.8.0"
412+
|| (matches!(evidence["schema_version"].as_str(), Some("0.8.0" | "0.9.0"))
406413
&& scan["native"]["edition_context"] != evidence["edition_context"])
407414
|| (evidence["schema_version"] == "0.7.0"
408415
&& (scan["native"]["gofmt_sha256"] != evidence["gofmt_sha256"]

‎crates/codeguard-cli/src/task_resolution_checker.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ impl TaskResolutionChecker {
5959
}
6060
/// 核对入口允许的签名策略版本;Zig 原生首次策略与旧 WASM 来源策略分开。
6161
pub(crate) fn accepts_policy_version(self, version: &str) -> bool {
62-
version == self.policy_version() || (matches!(self, Self::Zig) && version == "1.4.0")
62+
version == self.policy_version()
63+
|| (matches!(self, Self::Zig) && version == "1.4.0")
64+
|| (matches!(self, Self::Rust) && version == "1.8.0")
6365
}
6466
/// 返回该语言专用的脱敏证据版本;参数保留 Zig 原生首次来源与旧来源的区别。
6567
pub(crate) fn evidence_version(self, policy_version: &str) -> &'static str {
@@ -70,6 +72,7 @@ impl TaskResolutionChecker {
7072
Self::Swift => "0.3.0",
7173
Self::Kotlin => "0.4.0",
7274
Self::Go => "0.7.0",
75+
Self::Rust if policy_version == "1.8.0" => "0.9.0",
7376
Self::Rust => "0.8.0",
7477
}
7578
}

‎crates/codeguard-cli/src/task_resolution_evidence_shape.rs‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(crate) fn valid(record: &TaskLifecycleRecord, value: &Value) -> bool {
1919
"current_native",
2020
"outcome",
2121
];
22-
if value["schema_version"] == "0.8.0" {
22+
if matches!(value["schema_version"].as_str(), Some("0.8.0" | "0.9.0")) {
2323
expected.push("edition_context");
2424
if !valid_rust_binding(value) {
2525
return false;
@@ -112,13 +112,13 @@ fn native_bound(value: &Value) -> bool {
112112
Some("0.4.0") => "kotlinc-jvm 2.4.10",
113113
Some("0.6.0") => "ruff 0.16.8",
114114
Some("0.7.0") => "go1.23.4",
115-
Some("0.8.0") => "rustfmt 1.9.0-stable",
115+
Some("0.8.0" | "0.9.0") => "rustfmt 1.9.0-stable",
116116
_ => return false,
117117
};
118118
["original_native", "current_native"].iter().all(|k| {
119119
value[*k]["tool_sha256"] == value["tool_sha256"]
120120
&& value[*k]["version"] == version
121-
&& (value["schema_version"] != "0.8.0"
121+
&& (!matches!(value["schema_version"].as_str(), Some("0.8.0" | "0.9.0"))
122122
|| value[*k]["edition_context"] == value["edition_context"])
123123
&& (value["schema_version"] != "0.7.0"
124124
|| (value[*k]["gofmt_sha256"] == value["gofmt_sha256"]
@@ -128,7 +128,7 @@ fn native_bound(value: &Value) -> bool {
128128
fn native_for_version(evidence: &Value, key: &str) -> bool {
129129
match evidence["schema_version"].as_str() {
130130
Some("0.1.0" | "0.5.0") => native(&evidence[key]),
131-
Some("0.8.0") => crate::rust_syntax_evidence::valid(&evidence[key], None),
131+
Some("0.8.0" | "0.9.0") => crate::rust_syntax_evidence::valid(&evidence[key], None),
132132
Some("0.7.0") => crate::go_syntax_probe::valid_observation(&evidence[key], None),
133133
Some("0.6.0") => crate::python_syntax_probe::valid_native_observation(&evidence[key], None),
134134
Some("0.2.0") => crate::erlang_syntax_probe::valid_native_observation(&evidence[key], None),
@@ -273,7 +273,9 @@ pub(crate) fn valid_python_binding(value: &Value) -> bool {
273273
/// 参数为脱敏生命周期证据;结构有效仍须由宿主核验签名和当前字节。
274274
pub(crate) fn valid_rust_binding(value: &Value) -> bool {
275275
value["identity"]["checker_id"] == "syntax.native_confirmation"
276-
&& value["grammar_sha256"].is_null()
276+
&& ((value["schema_version"] == "0.8.0" && value["grammar_sha256"].is_null())
277+
|| (value["schema_version"] == "0.9.0"
278+
&& value["grammar_sha256"].as_str().is_some_and(digest)))
277279
&& value["edition_context"].is_object()
278280
&& ["original_native", "current_native"]
279281
.iter()

‎crates/codeguard-cli/src/task_resolution_service.rs‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn verify_go_task_resolution(
5656
verify_task_resolution(request, TaskResolutionChecker::Go)
5757
}
5858

59-
/// 验签宿主固定的Rust原生首次任务策略,并在同一Cargo edition下对照原反例与当前源码。
59+
/// 验签宿主固定的Rust原生首次或WASM首次任务策略,并在同一Cargo edition下对照原反例与当前源码。
6060
/// 参数来自受保护宿主;返回限定任务收据,不替代Clippy或全项目交付门禁。
6161
pub fn verify_rust_task_resolution(
6262
request: &crate::RustTaskResolutionRequest<'_>,
@@ -208,6 +208,14 @@ fn original_binding_matches(
208208
checker: TaskResolutionChecker,
209209
) -> bool {
210210
if checker.language() == "rust" {
211+
if policy.schema_version == "1.8.0" {
212+
return matches!(original["schema_version"].as_str(), Some("0.1.0" | "0.7.0"))
213+
&& original["native_evidence"].is_null()
214+
&& policy.grammar_sha256.as_ref().is_some_and(|grammar| {
215+
original["observations"][0]["source_sha256"] == policy.original_source_sha256
216+
&& original["observations"][0]["grammar_sha256"] == *grammar
217+
});
218+
}
211219
return original["schema_version"] == "0.12.0"
212220
&& policy.grammar_sha256.is_none()
213221
&& original["native_evidence"]["target"]["source_sha256"]
@@ -428,7 +436,10 @@ pub(crate) fn commit_resolution(
428436
"current_native",
429437
"outcome",
430438
];
431-
if raw_evidence["schema_version"] == "0.8.0" {
439+
if matches!(
440+
raw_evidence["schema_version"].as_str(),
441+
Some("0.8.0" | "0.9.0")
442+
) {
432443
keys.push("edition_context");
433444
if !crate::task_resolution_evidence_shape::valid_rust_binding(&raw_evidence) {
434445
return Err("task_resolution_evidence_binding_invalid");
@@ -454,7 +465,9 @@ pub(crate) fn commit_resolution(
454465
object.len() == keys.len() && keys.iter().all(|key| object.contains_key(*key))
455466
}) || !matches!(
456467
raw_evidence["schema_version"].as_str(),
457-
Some("0.1.0" | "0.2.0" | "0.3.0" | "0.4.0" | "0.5.0" | "0.6.0" | "0.7.0" | "0.8.0")
468+
Some(
469+
"0.1.0" | "0.2.0" | "0.3.0" | "0.4.0" | "0.5.0" | "0.6.0" | "0.7.0" | "0.8.0" | "0.9.0"
470+
)
458471
) {
459472
return Err("task_resolution_evidence_binding_invalid");
460473
}

0 commit comments

Comments
 (0)