diff --git a/README.md b/README.md index 1d053d1a..f0c10b7a 100644 --- a/README.md +++ b/README.md @@ -94,9 +94,9 @@ cargo build --locked -p codeguard-cli Version output includes `cli_version`, `target`, and protocol information. Discovery and init preview return observations and unknowns. Dry-run creates neither `AGENTS.md` nor a project data directory. Add Cargo `--offline` only when dependencies are cached. -The workspace requires `std`. The opt-in `wasm-precheck` build feature uses a bounded Rust worker with eleven pinned grammar candidates: C, Go, Java, JavaScript, Objective-C, Python, Rust, Solidity, TypeScript, TSX, and Zig. Java and TypeScript/TSX have narrow single-file fallback paths; `lint python` can provide bounded suspected syntax positions when Ruff is unavailable or no project Ruff configuration is declared. Native Ruff results take priority. It is absent from the published npm `0.1.2` package. No `no_std`, completed project-wide WASM fallback, zero-unsafe, or fastest-runtime claim is made. Runtime OS calls require safety review; a comprehensive security audit is not claimed. +The workspace requires `std`. The opt-in `wasm-precheck` build feature uses a bounded Rust worker with fifteen pinned grammar candidates: C, C++, C#, Go, Java, JavaScript, Lua, Luau, Objective-C, Python, Rust, Solidity, TypeScript, TSX, and Zig. Java and TypeScript/TSX have narrow single-file fallback paths; `lint python` can provide bounded suspected syntax positions when Ruff is unavailable or no project Ruff configuration is declared. Native Ruff results take priority. It is absent from the published npm `0.1.2` package. No `no_std`, completed project-wide WASM fallback, zero-unsafe, or fastest-runtime claim is made. Runtime OS calls require safety review; a comprehensive security audit is not claimed. -The current source-built CLI's `codeguard grammar status --format=json` reports the coverage gap without loading grammars or running lint: the pinned CodeGraph source has 30 vendored WASM files plus two distinct grammars resolved through its dependency; CodeGuard has eleven unqualified asset candidates (C, Go, Java, JavaScript, Objective-C, Python, Rust, Solidity, TypeScript, TSX, Zig) and zero released syntax capabilities. C, Go, JavaScript and Rust are byte-pinned CodeGraph assets that load in the Rust worker but have no public lint route or release qualification. The two dependency grammars retain their source bytes and use a byte-pinned legacy `dylink` metadata conversion for Rust loading; they have no public lint route or release qualification. Zig uses a byte-pinned import adaptation so the corrected CodeGraph grammar can load in Rust; it has no public `lint zig` route or release qualification yet. [Zig's limited acceptance record](tests/acceptance/zig-grammar-candidate.md) distinguishes this from released syntax support. Python has a source-build-only, unqualified CLI fallback path; its report remains incomplete and cannot approve delivery. The separate [coverage inventory](grammars/codegraph-coverage.json) is not an approved asset manifest. COBOL's 16.4 MB source asset also exceeds the current Rust loader's 8 MiB limit. +The current source-built CLI's `codeguard grammar status --format=json` reports the coverage gap without loading grammars or running lint: the pinned CodeGraph source has 30 vendored WASM files plus two distinct grammars resolved through its dependency; CodeGuard has fifteen unqualified asset candidates (C, C++, C#, Go, Java, JavaScript, Lua, Luau, Objective-C, Python, Rust, Solidity, TypeScript, TSX, Zig) and zero released syntax capabilities. C, C++, C#, Go, JavaScript, Lua, Luau and Rust are byte-pinned CodeGraph assets that load in the Rust worker but have no public lint route or release qualification. The two dependency grammars retain their source bytes and use a byte-pinned legacy `dylink` metadata conversion for Rust loading; they have no public lint route or release qualification. Zig uses a byte-pinned import adaptation so the corrected CodeGraph grammar can load in Rust; it has no public `lint zig` route or release qualification yet. [Zig's limited acceptance record](tests/acceptance/zig-grammar-candidate.md) distinguishes this from released syntax support. Python has a source-build-only, unqualified CLI fallback path; its report remains incomplete and cannot approve delivery. The separate [coverage inventory](grammars/codegraph-coverage.json) is not an approved asset manifest. COBOL's 16.4 MB source asset also exceeds the current Rust loader's 8 MiB limit. ### npm installation and one-off use diff --git a/README.zh-CN.md b/README.zh-CN.md index d7b7a778..4bf3a181 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -96,7 +96,7 @@ cargo build --locked -p codeguard-cli 工作区要求 `std`。可选 `wasm-precheck` 构建特性已用固定的 Java、Python、TypeScript、TSX grammar 候选资产与有界 Rust worker。Java 和 TypeScript/TSX 有局部单文件兜底;`lint python` 在 Ruff 不可用或项目未声明 Ruff 配置时可报告有界疑似语法位置,原生 Ruff 结果优先。公开 npm `0.1.2` 不含该路径。不声称 `no_std`、已完成项目级 WASM 兜底、零 unsafe 或性能最快。运行层系统调用需要安全审查,当前不宣称已完成整体安全审计。 -当前源码构建的 CLI 可用 `codeguard grammar status --format=json` 只读展示来源覆盖缺口,不加载 grammar 或运行 lint:固定 CodeGraph 来源含 30 份随仓 WASM,另有两种独立 grammar 从其依赖取得;CodeGuard 当前有 C、Go、Java、JavaScript、Objective-C、Python、Rust、Solidity、TypeScript、TSX、Zig 十一份未验收资产候选,已发行语法能力为零。C、Go、JavaScript、Rust 已作为固定字节的 Rust worker 候选接入,但没有公开 lint 路由或发行验收。Objective-C 与 Solidity 的依赖包原始字节、许可证和固定散列的 `dylink` 元数据转换已入库,可作为 Rust 隔离 worker 的候选观察,但没有公开 lint 路由或发行验收;Zig 也仍是未验收候选。Python 已有仅限源码可选构建的 CLI 候选兜底,结果保持不完整,不能批准交付。[覆盖库存](grammars/codegraph-coverage.json)不是已批准资产清单。COBOL 来源资产约 16.4 MB,还超过当前 Rust 加载器的 8 MiB 限额。 +当前源码构建的 CLI 可用 `codeguard grammar status --format=json` 只读展示来源覆盖缺口,不加载 grammar 或运行 lint:固定 CodeGraph 来源含 30 份随仓 WASM,另有两种独立 grammar 从其依赖取得;CodeGuard 当前有 C、C++、C#、Go、Java、JavaScript、Lua、Luau、Objective-C、Python、Rust、Solidity、TypeScript、TSX、Zig 十五份未验收资产候选,已发行语法能力为零。C、C++、C#、Go、JavaScript、Lua、Luau、Rust 已作为固定字节的 Rust worker 候选接入,但没有公开 lint 路由或发行验收。Objective-C 与 Solidity 的依赖包原始字节、许可证和固定散列的 `dylink` 元数据转换已入库,可作为 Rust 隔离 worker 的候选观察,但没有公开 lint 路由或发行验收;Zig 也仍是未验收候选。Python 已有仅限源码可选构建的 CLI 候选兜底,结果保持不完整,不能批准交付。[覆盖库存](grammars/codegraph-coverage.json)不是已批准资产清单。COBOL 来源资产约 16.4 MB,还超过当前 Rust 加载器的 8 MiB 限额。 ### npm 安装与一次性调用 diff --git a/crates/codeguard-adapters/src/grammar_asset_manifest.rs b/crates/codeguard-adapters/src/grammar_asset_manifest.rs index 168dc297..4185e155 100644 --- a/crates/codeguard-adapters/src/grammar_asset_manifest.rs +++ b/crates/codeguard-adapters/src/grammar_asset_manifest.rs @@ -15,6 +15,10 @@ const C_COMMIT: &str = "b780e47fc780ddc8da13afa35a3f4ed5c157823d"; const GO_COMMIT: &str = "3c3775faa968158a8b4ac190a7fda867fd5fb748"; const JAVASCRIPT_COMMIT: &str = "44c892e0be055ac465d5eeddae6d3e194424e7de"; const RUST_COMMIT: &str = "77a3747266f4d621d0757825e6b11edcbf991ca5"; +const CPP_COMMIT: &str = "f41e1a044c8a84ea9fa8577fdd2eab92ec96de02"; +const CSHARP_COMMIT: &str = "cac6d5fb595f5811a076336682d5d595ac1c9e85"; +const LUA_COMMIT: &str = "816840c592ab973500ae9750763c707b447e7fef"; +const LUAU_COMMIT: &str = "a8914d6c1fc5131f8e1c13f769fa704c9f5eb02f"; /// 代码来源、许可和每份候选 grammar 的固定身份。 #[derive(Clone, Debug, Deserialize, Eq, PartialEq)] @@ -50,6 +54,8 @@ pub struct GrammarAsset { pub language: String, /// 待验收的方言 ID。 pub dialect: String, + /// 与外部语言 ID 不同时,固定 WASM 的 tree_sitter_* 导出名。 + pub loader_symbol: Option, /// 上游 grammar 仓库。 pub grammar_repository: String, /// 上游 grammar 完整提交。 @@ -106,6 +112,14 @@ pub fn bundled_grammar_candidates() -> Result { include_bytes!("../../../grammars/c/parser.wasm").as_slice(), include_bytes!("../../../grammars/c/LICENSE").as_slice(), ), + "cpp" => ( + include_bytes!("../../../grammars/cpp/parser.wasm").as_slice(), + include_bytes!("../../../grammars/cpp/LICENSE").as_slice(), + ), + "csharp" => ( + include_bytes!("../../../grammars/csharp/parser.wasm").as_slice(), + include_bytes!("../../../grammars/csharp/LICENSE").as_slice(), + ), "go" => ( include_bytes!("../../../grammars/go/parser.wasm").as_slice(), include_bytes!("../../../grammars/go/LICENSE").as_slice(), @@ -114,6 +128,14 @@ pub fn bundled_grammar_candidates() -> Result { include_bytes!("../../../grammars/javascript/parser.wasm").as_slice(), include_bytes!("../../../grammars/javascript/LICENSE").as_slice(), ), + "lua" => ( + include_bytes!("../../../grammars/lua/parser.wasm").as_slice(), + include_bytes!("../../../grammars/lua/LICENSE").as_slice(), + ), + "luau" => ( + include_bytes!("../../../grammars/luau/parser.wasm").as_slice(), + include_bytes!("../../../grammars/luau/LICENSE").as_slice(), + ), "java" => ( include_bytes!("../../../grammars/java/parser.wasm").as_slice(), include_bytes!("../../../grammars/java/LICENSE").as_slice(), @@ -192,7 +214,7 @@ pub fn parse_grammar_asset_manifest(raw: &[u8]) -> Result Result Result ( + "https://github.com/tree-sitter/tree-sitter-cpp", + CPP_COMMIT, + "v0.23.4", + "cpp/parser.wasm", + "70f5e2b9976dad56bdcd1fafcb3af8c839c7a92e7beaa437162bcf45f390e83d", + 3434644, + "cpp/LICENSE", + "2e0110e07abef7c2548b26ec9d6969775617ca539a0dc8dbeeb14d6452c711d1", + ), + "csharp" => ( + "https://github.com/tree-sitter/tree-sitter-c-sharp", + CSHARP_COMMIT, + "v0.23.5", + "csharp/parser.wasm", + "6f69e1cae44e1c32c1eccc170dc5a9778fb94ff716f71113fe1f8c4299aa2f40", + 5350581, + "csharp/LICENSE", + "778fb7d63b8c1844da315648c02f325c4713a6f4a5d19644fd413421422776d3", + ), "go" => ( "https://github.com/tree-sitter/tree-sitter-go", GO_COMMIT, @@ -271,6 +317,26 @@ pub fn parse_grammar_asset_manifest(raw: &[u8]) -> Result ( + "https://github.com/tree-sitter-grammars/tree-sitter-lua", + LUA_COMMIT, + "v0.4.1", + "lua/parser.wasm", + "6d95607fc7d78964cfdf065ccb1ba76be5ed217c5ec0d0a3cace13c59fa1ae43", + 49488, + "lua/LICENSE", + "9a32b02e4c917b1ce6b5e79d8ea81e25cefd7f27d89c7235f2afb262c06cf32e", + ), + "luau" => ( + "https://github.com/tree-sitter-grammars/tree-sitter-luau", + LUAU_COMMIT, + "v1.2.0", + "luau/parser.wasm", + "f1647052518f2bdfae8e8c0b033ffdeca1193d69d11c78ba20f84c8374fd0fe3", + 94204, + "luau/LICENSE", + "099c44248f8cf353123211318680e93465587c005a4b3730ce8cb5334de043d6", + ), "rust" => ( "https://github.com/tree-sitter/tree-sitter-rust", RUST_COMMIT, @@ -334,6 +400,12 @@ pub fn parse_grammar_asset_manifest(raw: &[u8]) -> Result return Err("grammar 语言未知".into()), }; if asset.dialect != asset.language + || asset.loader_symbol.as_deref() + != if asset.language == "csharp" { + Some("c_sharp") + } else { + None + } || (match asset.language.as_str() { "objc" => { asset.source_wasm.as_deref() != Some("objc/source.wasm") @@ -360,7 +432,10 @@ pub fn parse_grammar_asset_manifest(raw: &[u8]) -> Result= schema["properties"]["assets"]["minItems"].as_u64().unwrap() as usize); + assert!(assets.len() <= schema["properties"]["assets"]["maxItems"].as_u64().unwrap() as usize); + assert_eq!( + schema["properties"]["build_tool"]["const"], + manifest["build_tool"] + ); + let root_fields = schema["properties"].as_object().unwrap(); + for name in manifest.as_object().unwrap().keys() { + assert!( + root_fields.contains_key(name), + "schema missing root field {name}" + ); + } + let asset_fields = schema["$defs"]["asset"]["properties"].as_object().unwrap(); + let languages = schema["$defs"]["asset"]["properties"]["language"]["enum"] + .as_array() + .unwrap(); + for asset in assets { + assert!( + languages.contains(&asset["language"]), + "schema missing {}", + asset["language"] + ); + for name in asset.as_object().unwrap().keys() { + assert!( + asset_fields.contains_key(name), + "schema missing asset field {name}" + ); + } + } + assert_eq!( + schema["$defs"]["asset"]["properties"]["release_status"]["const"], + "candidate_unvalidated" + ); +} #[test] fn bundled_candidates_pin_source_bytes_license_and_abi_without_claiming_support() { let manifest = bundled_grammar_candidates().expect("bundled manifest"); - assert_eq!(manifest.assets.len(), 11); + assert_eq!(manifest.assets.len(), 15); for asset in &manifest.assets { let (wasm, license) = match asset.language.as_str() { "c" => ( include_bytes!("../../../grammars/c/parser.wasm").as_slice(), include_bytes!("../../../grammars/c/LICENSE").as_slice(), ), + "cpp" => ( + include_bytes!("../../../grammars/cpp/parser.wasm").as_slice(), + include_bytes!("../../../grammars/cpp/LICENSE").as_slice(), + ), + "csharp" => ( + include_bytes!("../../../grammars/csharp/parser.wasm").as_slice(), + include_bytes!("../../../grammars/csharp/LICENSE").as_slice(), + ), "go" => ( include_bytes!("../../../grammars/go/parser.wasm").as_slice(), include_bytes!("../../../grammars/go/LICENSE").as_slice(), @@ -21,6 +75,14 @@ fn bundled_candidates_pin_source_bytes_license_and_abi_without_claiming_support( include_bytes!("../../../grammars/javascript/parser.wasm").as_slice(), include_bytes!("../../../grammars/javascript/LICENSE").as_slice(), ), + "lua" => ( + include_bytes!("../../../grammars/lua/parser.wasm").as_slice(), + include_bytes!("../../../grammars/lua/LICENSE").as_slice(), + ), + "luau" => ( + include_bytes!("../../../grammars/luau/parser.wasm").as_slice(), + include_bytes!("../../../grammars/luau/LICENSE").as_slice(), + ), "java" => ( include_bytes!("../../../grammars/java/parser.wasm").as_slice(), include_bytes!("../../../grammars/java/LICENSE").as_slice(), @@ -109,6 +171,12 @@ fn missing_provenance_duplicate_fields_and_unknown_languages_are_rejected() { assert!(parse_grammar_asset_manifest(duplicate.as_bytes()).is_err()); let unknown = original.replacen("\"language\": \"java\"", "\"language\": \"unknown\"", 1); assert!(parse_grammar_asset_manifest(unknown.as_bytes()).is_err()); + let wrong_symbol = original.replacen( + "\"loader_symbol\": \"c_sharp\"", + "\"loader_symbol\": \"csharp\"", + 1, + ); + assert!(parse_grammar_asset_manifest(wrong_symbol.as_bytes()).is_err()); } #[test] diff --git a/crates/codeguard-cli/src/syntax_worker_command.rs b/crates/codeguard-cli/src/syntax_worker_command.rs index e5d1b994..9900b36e 100644 --- a/crates/codeguard-cli/src/syntax_worker_command.rs +++ b/crates/codeguard-cli/src/syntax_worker_command.rs @@ -65,8 +65,12 @@ fn observe(language: &str, source: &[u8]) -> Result include_bytes!("../../../grammars/c/parser.wasm").as_slice(), + "cpp" => include_bytes!("../../../grammars/cpp/parser.wasm").as_slice(), + "csharp" => include_bytes!("../../../grammars/csharp/parser.wasm").as_slice(), "go" => include_bytes!("../../../grammars/go/parser.wasm").as_slice(), "javascript" => include_bytes!("../../../grammars/javascript/parser.wasm").as_slice(), + "lua" => include_bytes!("../../../grammars/lua/parser.wasm").as_slice(), + "luau" => include_bytes!("../../../grammars/luau/parser.wasm").as_slice(), "java" => include_bytes!("../../../grammars/java/parser.wasm").as_slice(), "python" => include_bytes!("../../../grammars/python/parser.wasm").as_slice(), "typescript" => include_bytes!("../../../grammars/typescript/parser.wasm").as_slice(), @@ -77,7 +81,12 @@ fn observe(language: &str, source: &[u8]) -> Result include_bytes!("../../../grammars/rust/parser.wasm").as_slice(), _ => return Err("不支持的 grammar 语种".into()), }; - let mut grammar = WasmGrammar::load(language, wasm, &asset.sha256, asset.abi_version as usize)?; + let mut grammar = WasmGrammar::load( + asset.loader_symbol.as_deref().unwrap_or(language), + wasm, + &asset.sha256, + asset.abi_version as usize, + )?; let tree = grammar.parse(source)?; let scanned = scan_wasm_recoveries(&tree, MAX_RECOVERIES)?; let recoveries = scanned diff --git a/crates/codeguard-cli/tests/grammar_status_cli.rs b/crates/codeguard-cli/tests/grammar_status_cli.rs index 27bc650d..3c262c78 100644 --- a/crates/codeguard-cli/tests/grammar_status_cli.rs +++ b/crates/codeguard-cli/tests/grammar_status_cli.rs @@ -12,7 +12,7 @@ fn codegraph_coverage_is_explicit_and_never_claims_parser_or_gate_completion() { assert_eq!(report["report_type"], "grammar_coverage_inventory"); assert_eq!(report["codegraph_grammar_count"], 32); assert_eq!(report["codegraph_vendored_count"], 30); - assert_eq!(report["candidate_count"], 11); + assert_eq!(report["candidate_count"], 15); assert_eq!(report["released_count"], 0); assert_eq!(report["authority"], "source_inventory_only"); assert_eq!(report["parser_capability"], "unverified"); @@ -27,9 +27,13 @@ fn codegraph_coverage_is_explicit_and_never_claims_parser_or_gate_completion() { } for language in [ "c", + "cpp", + "csharp", "go", "java", "javascript", + "lua", + "luau", "objc", "python", "rust", diff --git a/crates/codeguard-cli/tests/syntax_worker_candidate.rs b/crates/codeguard-cli/tests/syntax_worker_candidate.rs index 7589dd55..740a1e8d 100644 --- a/crates/codeguard-cli/tests/syntax_worker_candidate.rs +++ b/crates/codeguard-cli/tests/syntax_worker_candidate.rs @@ -133,6 +133,37 @@ fn mainstream_grammars_run_in_worker_without_claiming_clean() { } } +#[test] +fn cpp_csharp_lua_and_luau_run_in_worker_without_claiming_clean() { + for (language, path, source) in [ + ( + "cpp", + "src/main.cpp", + b"int main() { return 0; }".as_slice(), + ), + ( + "csharp", + "src/C.cs", + b"class C { static int F() { return 1; } }".as_slice(), + ), + ("lua", "src/main.lua", b"local x = 1\n".as_slice()), + ("luau", "src/main.luau", b"local x: number = 1\n".as_slice()), + ] { + let result = run_syntax_worker_candidate( + env!("CARGO_BIN_EXE_codeguard").as_ref(), + language, + path, + source, + Instant::now() + Duration::from_secs(60), + &AtomicBool::new(false), + ) + .expect("grammar worker candidate"); + assert!(result.recoveries.is_empty(), "{language}"); + assert_eq!(result.precheck.status, SyntaxPrecheckStatus::Incomplete); + assert!(!result.grammar_qualified); + } +} + #[test] fn invalid_input_and_cancellation_cannot_yield_observations() { let exe = env!("CARGO_BIN_EXE_codeguard").as_ref(); diff --git a/crates/codeguard-runtime/tests/wasm_grammar_load.rs b/crates/codeguard-runtime/tests/wasm_grammar_load.rs index 62006ff5..0031fb96 100644 --- a/crates/codeguard-runtime/tests/wasm_grammar_load.rs +++ b/crates/codeguard-runtime/tests/wasm_grammar_load.rs @@ -14,6 +14,59 @@ const C: &[u8] = include_bytes!("../../../grammars/c/parser.wasm"); const GO: &[u8] = include_bytes!("../../../grammars/go/parser.wasm"); const JAVASCRIPT: &[u8] = include_bytes!("../../../grammars/javascript/parser.wasm"); const RUST: &[u8] = include_bytes!("../../../grammars/rust/parser.wasm"); +const CPP: &[u8] = include_bytes!("../../../grammars/cpp/parser.wasm"); +const CSHARP: &[u8] = include_bytes!("../../../grammars/csharp/parser.wasm"); +const LUA: &[u8] = include_bytes!("../../../grammars/lua/parser.wasm"); +const LUAU: &[u8] = include_bytes!("../../../grammars/luau/parser.wasm"); + +#[test] +fn second_batch_grammars_load_offline_and_parse_basic_fixtures() { + for (name, wasm, sha, abi, valid, invalid) in [ + ( + "cpp", + CPP, + "70f5e2b9976dad56bdcd1fafcb3af8c839c7a92e7beaa437162bcf45f390e83d", + 14, + b"int main() { return 0; }".as_slice(), + b"int main() {".as_slice(), + ), + ( + "c_sharp", + CSHARP, + "6f69e1cae44e1c32c1eccc170dc5a9778fb94ff716f71113fe1f8c4299aa2f40", + 15, + b"class C { static int F() { return 1; } }".as_slice(), + b"class C {".as_slice(), + ), + ( + "lua", + LUA, + "6d95607fc7d78964cfdf065ccb1ba76be5ed217c5ec0d0a3cace13c59fa1ae43", + 15, + b"local x = 1\n".as_slice(), + b"local =\n".as_slice(), + ), + ( + "luau", + LUAU, + "f1647052518f2bdfae8e8c0b033ffdeca1193d69d11c78ba20f84c8374fd0fe3", + 14, + b"local x: number = 1\n".as_slice(), + b"local x: =\n".as_slice(), + ), + ] { + let mut grammar = WasmGrammar::load(name, wasm, sha, abi) + .unwrap_or_else(|reason| panic!("{name} offline load: {reason}")); + assert!( + !grammar.parse(valid).unwrap().root_node().has_error(), + "{name} valid" + ); + assert!( + grammar.parse(invalid).unwrap().root_node().has_error(), + "{name} invalid" + ); + } +} #[test] fn mainstream_grammars_load_offline_and_parse_basic_fixtures() { diff --git a/docs/Codeguard-Architecture.md b/docs/Codeguard-Architecture.md index c07bca1e..4d78b327 100644 --- a/docs/Codeguard-Architecture.md +++ b/docs/Codeguard-Architecture.md @@ -28,7 +28,7 @@ The existing [OpenSpec change](../openspec/changes/introduce-rust-codeguard-cli/ | [Core aggregation](../crates/codeguard-core/src/aggregate.rs), [delivery gate](../crates/codeguard-core/src/delivery_gate.rs) | Pure result semantics, not trusted public gate availability | | [Acceptance records](../tests/acceptance) | Scoped observations, test method, and residual gaps | -WASM requirements and 19 implementation tasks are recorded in the existing change. An opt-in Rust worker and narrow Java/TypeScript/TSX single-file feedback paths and a Python Ruff-unavailable candidate path now exist. All eleven grammars remain unqualified; C, Go, JavaScript, Rust, Zig, Objective-C and Solidity are pinned Rust-loadable candidates without public lint routes. Project-wide native-first routing, qualified grammar ranges, capability-matched task closure, and host integrations remain incomplete; design examples are not current command output. +WASM requirements and 19 implementation tasks are recorded in the existing change. An opt-in Rust worker and narrow Java/TypeScript/TSX single-file feedback paths and a Python Ruff-unavailable candidate path now exist. All fifteen grammars remain unqualified; C, C++, C#, Go, JavaScript, Lua, Luau, Rust, Zig, Objective-C and Solidity are pinned Rust-loadable candidates without public lint routes. Project-wide native-first routing, qualified grammar ranges, capability-matched task closure, and host integrations remain incomplete; design examples are not current command output. ## 2. Architectural drivers diff --git a/docs/Codeguard-Architecture.zh_CN.md b/docs/Codeguard-Architecture.zh_CN.md index d32eea71..2d32ee09 100644 --- a/docs/Codeguard-Architecture.zh_CN.md +++ b/docs/Codeguard-Architecture.zh_CN.md @@ -28,7 +28,7 @@ | [核心聚合](../crates/codeguard-core/src/aggregate.rs)、[交付门禁](../crates/codeguard-core/src/delivery_gate.rs) | 纯结果语义,不代表公开可信门禁已可用 | | [验收记录](../tests/acceptance) | 限定范围的观察、测试方法和剩余缺口 | -WASM 的规范与 19 项实施任务已纳入既有 change;可选 Rust worker 与 Java/TypeScript/TSX 局部单文件反馈路径及 Python Ruff 不可用时的候选路径已存在;十一份 grammar 都尚未验收;C、Go、JavaScript、Rust、Zig、Objective-C、Solidity 仅有固定字节的 Rust 可加载候选资产,尚无公开 lint 路由。项目级原生优先调度、grammar 版本范围验收、任务的能力匹配关闭及宿主接线仍未完成;设计示例不是当前命令输出。 +WASM 的规范与 19 项实施任务已纳入既有 change;可选 Rust worker 与 Java/TypeScript/TSX 局部单文件反馈路径及 Python Ruff 不可用时的候选路径已存在;十五份 grammar 都尚未验收;C、C++、C#、Go、JavaScript、Lua、Luau、Rust、Zig、Objective-C、Solidity 仅有固定字节的 Rust 可加载候选资产,尚无公开 lint 路由。项目级原生优先调度、grammar 版本范围验收、任务的能力匹配关闭及宿主接线仍未完成;设计示例不是当前命令输出。 ## 2. 架构驱动 @@ -241,7 +241,7 @@ flowchart TD 复用固定版本的 CodeGraph grammar WASM,以及适用的上游许可证、源码引用、补丁和语料。不能把 CodeGraph 的图提取或源码遮盖启发式直接用于语法判定。CodeGraph 的 `src/extraction/grammars.ts` 通过 `web-tree-sitter` 加载语言资产,在那里可加载不证明兼容 Codeguard 的 Rust 运行时。发行时必须固定不可变的来源与资产清单,不能把正在修改的本地目录直接当作发行输入。 -只读 `codeguard grammar status` 现投影[固定来源覆盖库存](../grammars/codegraph-coverage.json):CodeGraph 随仓 30 份 WASM,依赖提供另两种独立 grammar;CodeGuard 有 C、Go、Java、JavaScript、Objective-C、Python、Rust、Solidity、TypeScript、TSX、Zig 十一份资产候选。C、Go、JavaScript、Rust 的 CodeGraph 随仓字节及上游标签许可证已固定,可由 Rust worker 解析基础正反例,但尚未进行语言验收或公开 lint 接线。Objective-C 与 Solidity 来自锁定的 `tree-sitter-wasms@0.1.13`,保留原始字节和许可证,并以固定散列的 `dylink` 元数据转换加载;仍未做语言验收与发行。Zig 新版来源 WASM 的导入经固定哈希适配后由 Rust 加载,但仍无公开 `lint zig` 路由,尚无已验收发行能力。Python 已有源码可选构建中的局部 `lint` 兜底,仅覆盖 Ruff 不可用或项目未声明配置的情形;原生结果优先且不能批准交付。已初始化工作区的单文件范围可同步稳定的原生确认任务;候选零恢复节点不会关闭任务。覆盖库存与[候选资产清单](../grammars/manifest.json)分开,不能凭库存行自动加载或宣称支持。尤其 COBOL 来源资产超过当前加载器 8 MiB 限额。 +只读 `codeguard grammar status` 现投影[固定来源覆盖库存](../grammars/codegraph-coverage.json):CodeGraph 随仓 30 份 WASM,依赖提供另两种独立 grammar;CodeGuard 有 C、C++、C#、Go、Java、JavaScript、Lua、Luau、Objective-C、Python、Rust、Solidity、TypeScript、TSX、Zig 十五份资产候选。C、C++、C#、Go、JavaScript、Lua、Luau、Rust 的 CodeGraph 随仓字节及上游标签许可证已固定,可由 Rust worker 解析基础正反例,但尚未进行语言验收或公开 lint 接线。Objective-C 与 Solidity 来自锁定的 `tree-sitter-wasms@0.1.13`,保留原始字节和许可证,并以固定散列的 `dylink` 元数据转换加载;仍未做语言验收与发行。Zig 新版来源 WASM 的导入经固定哈希适配后由 Rust 加载,但仍无公开 `lint zig` 路由,尚无已验收发行能力。Python 已有源码可选构建中的局部 `lint` 兜底,仅覆盖 Ruff 不可用或项目未声明配置的情形;原生结果优先且不能批准交付。已初始化工作区的单文件范围可同步稳定的原生确认任务;候选零恢复节点不会关闭任务。覆盖库存与[候选资产清单](../grammars/manifest.json)分开,不能凭库存行自动加载或宣称支持。尤其 COBOL 来源资产超过当前加载器 8 MiB 限额。 ```text grammars/ # 规划中的发行资产,不是项目状态 diff --git a/docs/Codeguard-Technical-Design.md b/docs/Codeguard-Technical-Design.md index 6dd11377..a4c480e6 100644 --- a/docs/Codeguard-Technical-Design.md +++ b/docs/Codeguard-Technical-Design.md @@ -14,7 +14,7 @@ The existing [OpenSpec change](../openspec/changes/introduce-rust-codeguard-cli/ Current source is the authority for callable behavior. Target contracts are labelled as such. The product priority is configuration discovery → native results → useful repair guidance. Internal consistency checks support this experience; they are not a demand for users to manually construct execution certificates. -WASM requirements and 19 implementation tasks are recorded in the existing change. Candidate Rust worker and narrow Java/TypeScript/TSX single-file reports and a Python Ruff-unavailable candidate report now exist behind an opt-in feature; all eleven grammars remain unqualified; C, Go, JavaScript, Rust, Zig, Objective-C and Solidity are only Rust-loadable candidates. Project-wide native-first routing, qualified grammar ranges, and host integrations remain incomplete. Design examples are not current command output. +WASM requirements and 19 implementation tasks are recorded in the existing change. Candidate Rust worker and narrow Java/TypeScript/TSX single-file reports and a Python Ruff-unavailable candidate report now exist behind an opt-in feature; all fifteen grammars remain unqualified; C, C++, C#, Go, JavaScript, Lua, Luau, Rust, Zig, Objective-C and Solidity are only Rust-loadable candidates. Project-wide native-first routing, qualified grammar ranges, and host integrations remain incomplete. Design examples are not current command output. ## 2. Technology choices and trade-offs @@ -191,7 +191,7 @@ The opt-in CLI build first checks for a local ESLint 10 package and a single ord Import only pinned WASM bytes with upstream license, commit/patch provenance, SHA-256, ABI, tested runtime and language/dialect ranges, corpus reference and known gaps. Verify each copied CodeGraph artifact in the selected Rust Tree-sitter runtime; do not copy TypeScript extraction logic or assume CodeGraph support equals syntax acceptance. A release manifest belongs to distribution assets, not writable `.codeguard/` project state. -Use `codeguard grammar status --format=json` to query the separate source coverage inventory. It reports 32 distinct CodeGraph grammar assets, eleven CodeGuard asset candidates (C, Go, Java, JavaScript, Objective-C, Python, Rust, Solidity, TypeScript, TSX and Zig), and zero released capabilities without running a parser. Python has a narrow source-build-only `lint` fallback for unavailable or undeclared Ruff, never a clean or delivery result. A bound, single-file result uses [feedback 0.15.0](../schemas/python-lint-feedback-v0.15.schema.json) and persists a [0.1.0 confirmation observation](../schemas/python-syntax-confirmation-observation-v0.1.schema.json) through the existing work sync. The task identity binds workspace and source scope; current-source SHA-256 and pinned grammar are checked before import. Native capability-matched closure remains open. C, Go, JavaScript and Rust have pinned vendored bytes and narrow Rust worker smoke tests, but no public lint route or language qualification. The two dependency-provided assets now have pinned original and adapted bytes plus license references, but are still unqualified candidates without public lint routes. COBOL exceeds the current 8 MiB loader limit. +Use `codeguard grammar status --format=json` to query the separate source coverage inventory. It reports 32 distinct CodeGraph grammar assets, fifteen CodeGuard asset candidates (C, C++, C#, Go, Java, JavaScript, Lua, Luau, Objective-C, Python, Rust, Solidity, TypeScript, TSX and Zig), and zero released capabilities without running a parser. Python has a narrow source-build-only `lint` fallback for unavailable or undeclared Ruff, never a clean or delivery result. A bound, single-file result uses [feedback 0.15.0](../schemas/python-lint-feedback-v0.15.schema.json) and persists a [0.1.0 confirmation observation](../schemas/python-syntax-confirmation-observation-v0.1.schema.json) through the existing work sync. The task identity binds workspace and source scope; current-source SHA-256 and pinned grammar are checked before import. Native capability-matched closure remains open. C, C++, C#, Go, JavaScript, Lua, Luau and Rust have pinned vendored bytes and narrow Rust worker smoke tests, but no public lint route or language qualification. The two dependency-provided assets now have pinned original and adapted bytes plus license references, but are still unqualified candidates without public lint routes. COBOL exceeds the current 8 MiB loader limit. Use a parent-controlled parser worker with a total deadline, per-file input bound, memory/process limit and capped diagnostics. Lazy-load selected grammars, parse without general network/filesystem imports, and terminate a stuck worker without losing native results from other modules. Host-specific enforcement and Rust MSRV compatibility must be tested; numeric production budgets remain measurement-driven rather than invented promises. diff --git a/docs/Codeguard-Technical-Design.zh_CN.md b/docs/Codeguard-Technical-Design.zh_CN.md index dcfd2e9d..1c72b0a1 100644 --- a/docs/Codeguard-Technical-Design.zh_CN.md +++ b/docs/Codeguard-Technical-Design.zh_CN.md @@ -14,7 +14,7 @@ 可调用行为以当前源码为准,目标契约明确标注。产品优先级是配置发现 → 原生结果 → 有用的修复指引。内部一致性校验为这个体验服务,不要求用户手工构造执行证明。 -WASM 的规范与 19 项实施任务已纳入既有 change;可选特性下的 Rust worker 与 Java/TypeScript/TSX 局部单文件候选报告及 Python Ruff 不可用时的候选报告已存在;十一份 grammar 均未验收;C、Go、JavaScript、Rust、Zig、Objective-C、Solidity 仅有固定字节的 Rust 可加载候选资产,尚无公开 lint 路由。项目级原生优先调度、grammar 版本范围验收与宿主接线仍未完成。设计示例不是当前命令输出。 +WASM 的规范与 19 项实施任务已纳入既有 change;可选特性下的 Rust worker 与 Java/TypeScript/TSX 局部单文件候选报告及 Python Ruff 不可用时的候选报告已存在;十五份 grammar 均未验收;C、C++、C#、Go、JavaScript、Lua、Luau、Rust、Zig、Objective-C、Solidity 仅有固定字节的 Rust 可加载候选资产,尚无公开 lint 路由。项目级原生优先调度、grammar 版本范围验收与宿主接线仍未完成。设计示例不是当前命令输出。 ## 2. 技术选型与权衡 @@ -191,7 +191,7 @@ flowchart LR 只引入固定 WASM 字节及上游许可证、提交/补丁来源、SHA-256、ABI、已验证运行时和语言/方言范围、语料引用与已知缺口。逐个验证 CodeGraph 资产与选定 Rust Tree-sitter 运行时兼容,不能复制 TypeScript 提取逻辑或把 CodeGraph 支持等同语法验收。发行清单属于分发资产,不属于可写的 `.codeguard/` 项目状态。 -可用 `codeguard grammar status --format=json` 查询独立的来源覆盖库存。它只读报告 CodeGraph 32 种独立 grammar、CodeGuard 十一份资产候选(C、Go、Java、JavaScript、Objective-C、Python、Rust、Solidity、TypeScript、TSX、Zig)和零项已发行能力,不运行解析器;Python 已有源码可选构建中的局部 `lint` 兜底,结果不能视为通过。已绑定工作区的单文件反馈使用 [0.15.0 协议](../schemas/python-lint-feedback-v0.15.schema.json),并通过现有 work sync 保存 [0.1.0 确认观察](../schemas/python-syntax-confirmation-observation-v0.1.schema.json)。任务身份绑定工作区和源码范围;导入前核对当前源码 SHA-256 与固定 grammar。能力匹配的原生关闭仍未完成。C、Go、JavaScript、Rust 的随仓字节和上游许可证已固定,完成窄范围 Rust worker 解析验证,尚无公开 lint 路由或语言验收。依赖提供的 Objective-C 与 Solidity 已固定原始和适配后字节、许可证及依赖包完整性,但仍未验收语言版本或公开 lint 路由;COBOL 超过现有加载器的 8 MiB 限额。 +可用 `codeguard grammar status --format=json` 查询独立的来源覆盖库存。它只读报告 CodeGraph 32 种独立 grammar、CodeGuard 十五份资产候选(C、C++、C#、Go、Java、JavaScript、Lua、Luau、Objective-C、Python、Rust、Solidity、TypeScript、TSX、Zig)和零项已发行能力,不运行解析器;Python 已有源码可选构建中的局部 `lint` 兜底,结果不能视为通过。已绑定工作区的单文件反馈使用 [0.15.0 协议](../schemas/python-lint-feedback-v0.15.schema.json),并通过现有 work sync 保存 [0.1.0 确认观察](../schemas/python-syntax-confirmation-observation-v0.1.schema.json)。任务身份绑定工作区和源码范围;导入前核对当前源码 SHA-256 与固定 grammar。能力匹配的原生关闭仍未完成。C、C++、C#、Go、JavaScript、Lua、Luau、Rust 的随仓字节和上游许可证已固定,完成窄范围 Rust worker 解析验证,尚无公开 lint 路由或语言验收。依赖提供的 Objective-C 与 Solidity 已固定原始和适配后字节、许可证及依赖包完整性,但仍未验收语言版本或公开 lint 路由;COBOL 超过现有加载器的 8 MiB 限额。 由父进程控制解析工作进程,设置总截止时间、单文件输入上限、内存/进程限制及诊断数量上限。按需加载 grammar,不提供通用网络/文件系统导入;终止卡住的进程时保留其它模块的原生结果。宿主约束执行和 Rust MSRV 兼容性须测试,生产数值预算须经测量后确定,不编造性能承诺。 diff --git a/grammars/cpp/LICENSE b/grammars/cpp/LICENSE new file mode 100644 index 00000000..4b52d191 --- /dev/null +++ b/grammars/cpp/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Max Brunsfeld + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/grammars/cpp/parser.wasm b/grammars/cpp/parser.wasm new file mode 100644 index 00000000..cba731bc Binary files /dev/null and b/grammars/cpp/parser.wasm differ diff --git a/grammars/csharp/LICENSE b/grammars/csharp/LICENSE new file mode 100644 index 00000000..c8921f69 --- /dev/null +++ b/grammars/csharp/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2023 Max Brunsfeld, Damien Guard, Amaan Qureshi, and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/grammars/csharp/parser.wasm b/grammars/csharp/parser.wasm new file mode 100644 index 00000000..bddfd5c8 Binary files /dev/null and b/grammars/csharp/parser.wasm differ diff --git a/grammars/lua/LICENSE b/grammars/lua/LICENSE new file mode 100644 index 00000000..ff0407e7 --- /dev/null +++ b/grammars/lua/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2021 Munif Tanjim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/grammars/lua/parser.wasm b/grammars/lua/parser.wasm new file mode 100644 index 00000000..be3231dc Binary files /dev/null and b/grammars/lua/parser.wasm differ diff --git a/grammars/luau/LICENSE b/grammars/luau/LICENSE new file mode 100644 index 00000000..5af53636 --- /dev/null +++ b/grammars/luau/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2023 Amaan Qureshi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/grammars/luau/parser.wasm b/grammars/luau/parser.wasm new file mode 100644 index 00000000..1ed5af18 Binary files /dev/null and b/grammars/luau/parser.wasm differ diff --git a/grammars/manifest.json b/grammars/manifest.json index 9321e185..ec72dd4d 100644 --- a/grammars/manifest.json +++ b/grammars/manifest.json @@ -26,6 +26,47 @@ ], "release_status": "candidate_unvalidated" }, + { + "language": "cpp", + "dialect": "cpp", + "grammar_repository": "https://github.com/tree-sitter/tree-sitter-cpp", + "grammar_commit": "f41e1a044c8a84ea9fa8577fdd2eab92ec96de02", + "grammar_version": "v0.23.4", + "path": "cpp/parser.wasm", + "sha256": "70f5e2b9976dad56bdcd1fafcb3af8c839c7a92e7beaa437162bcf45f390e83d", + "bytes": 3434644, + "license": "cpp/LICENSE", + "license_sha256": "2e0110e07abef7c2548b26ec9d6969775617ca539a0dc8dbeeb14d6452c711d1", + "abi_version": 14, + "codegraph_runtime": "web-tree-sitter 0.25.3", + "codeguard_runtime_validation": "rust_loader_smoke_passed", + "language_versions": [], + "known_limitations": [ + "Rust loader smoke and narrow fixtures passed; language versions, dialect corpus, native differential, resource isolation and release remain unqualified" + ], + "release_status": "candidate_unvalidated" + }, + { + "language": "csharp", + "dialect": "csharp", + "grammar_repository": "https://github.com/tree-sitter/tree-sitter-c-sharp", + "grammar_commit": "cac6d5fb595f5811a076336682d5d595ac1c9e85", + "grammar_version": "v0.23.5", + "path": "csharp/parser.wasm", + "sha256": "6f69e1cae44e1c32c1eccc170dc5a9778fb94ff716f71113fe1f8c4299aa2f40", + "bytes": 5350581, + "license": "csharp/LICENSE", + "license_sha256": "778fb7d63b8c1844da315648c02f325c4713a6f4a5d19644fd413421422776d3", + "abi_version": 15, + "codegraph_runtime": "web-tree-sitter 0.25.3", + "codeguard_runtime_validation": "rust_loader_smoke_passed", + "language_versions": [], + "known_limitations": [ + "Rust loader smoke and narrow fixtures passed; language versions, dialect corpus, native differential, resource isolation and release remain unqualified" + ], + "release_status": "candidate_unvalidated", + "loader_symbol": "c_sharp" + }, { "language": "go", "dialect": "go", @@ -86,6 +127,46 @@ ], "release_status": "candidate_unvalidated" }, + { + "language": "lua", + "dialect": "lua", + "grammar_repository": "https://github.com/tree-sitter-grammars/tree-sitter-lua", + "grammar_commit": "816840c592ab973500ae9750763c707b447e7fef", + "grammar_version": "v0.4.1", + "path": "lua/parser.wasm", + "sha256": "6d95607fc7d78964cfdf065ccb1ba76be5ed217c5ec0d0a3cace13c59fa1ae43", + "bytes": 49488, + "license": "lua/LICENSE", + "license_sha256": "9a32b02e4c917b1ce6b5e79d8ea81e25cefd7f27d89c7235f2afb262c06cf32e", + "abi_version": 15, + "codegraph_runtime": "web-tree-sitter 0.25.3", + "codeguard_runtime_validation": "rust_loader_smoke_passed", + "language_versions": [], + "known_limitations": [ + "Rust loader smoke and narrow fixtures passed; language versions, dialect corpus, native differential, resource isolation and release remain unqualified" + ], + "release_status": "candidate_unvalidated" + }, + { + "language": "luau", + "dialect": "luau", + "grammar_repository": "https://github.com/tree-sitter-grammars/tree-sitter-luau", + "grammar_commit": "a8914d6c1fc5131f8e1c13f769fa704c9f5eb02f", + "grammar_version": "v1.2.0", + "path": "luau/parser.wasm", + "sha256": "f1647052518f2bdfae8e8c0b033ffdeca1193d69d11c78ba20f84c8374fd0fe3", + "bytes": 94204, + "license": "luau/LICENSE", + "license_sha256": "099c44248f8cf353123211318680e93465587c005a4b3730ce8cb5334de043d6", + "abi_version": 14, + "codegraph_runtime": "web-tree-sitter 0.25.3", + "codeguard_runtime_validation": "rust_loader_smoke_passed", + "language_versions": [], + "known_limitations": [ + "Rust loader smoke and narrow fixtures passed; language versions, dialect corpus, native differential, resource isolation and release remain unqualified" + ], + "release_status": "candidate_unvalidated" + }, { "language": "objc", "dialect": "objc", diff --git a/openspec/changes/introduce-rust-codeguard-cli/tasks.md b/openspec/changes/introduce-rust-codeguard-cli/tasks.md index 1e6bb333..d2d79121 100644 --- a/openspec/changes/introduce-rust-codeguard-cli/tasks.md +++ b/openspec/changes/introduce-rust-codeguard-cli/tasks.md @@ -1028,7 +1028,7 @@ TDD缺自动同步先RED。相关普通:build9、work sync15、next6,共30 状态:逐项实施中,未达到整体验收。统一规格 [syntax-precheck](specs/syntax-precheck/spec.md)。依赖已有 CLI/原生调度/工作台切片,不等待整个 S13;本阶段验收进入 S12、S13。各任务须先失败样本后实现与回归;不改写原生规则。责任为模块维护职责,非已分配人员。 -- [ ] 14.1 资产清单与来源。责任:adapters / 发布。规格:SP04。依赖:无。验收:固定 CodeGraph 来源提交、grammar 版本、许可证、SHA-256、ABI、语言/方言;缺来源、错散列和不兼容样本拒绝加载。进行中:已从固定 CodeGraph 提交复制 Java/Python/TypeScript/TSX WASM 与 MIT 许可证,清单和 Rust 校验拒绝来源/字节/声明 ABI 漂移;四份资产已由 Rust 离线加载并实测 ABI,Python 尚无 lint 路由;见[Python 资产局部验收](../../../tests/acceptance/python-grammar-asset-candidate.md);[局部证据](../../../tests/acceptance/grammar-asset-candidates.md)。新增与批准资产清单分离的[完整来源覆盖库存](../../../grammars/codegraph-coverage.json)及只读 `grammar status`:固定提交中的 30 份随仓 WASM 已逐字节核对,另两种依赖资产标为未固定,COBOL 的 16.4 MB 超出当前 8 MiB 加载限额;[覆盖验收](../../../tests/acceptance/codegraph-grammar-coverage.md)。其余 grammar 的上游许可证/版本、Rust 加载,以及所有候选的语言版本/方言、语料及可发行验收仍缺,不勾选。 Python 资产已接入可选源码构建的 `lint python` 局部候选路径,但版本/方言和发行验收仍缺;见[Python 兜底局部验收](../../../tests/acceptance/python-syntax-fallback-candidate.md)。 2026-09-29 增量:CodeGraph 来源更新至 `1072f82ce24db3d133258d30165cef6b74d108b2`,30/30 随仓字节与新提交一致。新增 Zig 第五份候选:保留新版原始 WASM、许可证和固定哈希;原始模块因 `__main_argc_argv` 不被 Rust `WasmStore` 接受,使用固定输入/输出散列的同签名导入适配后,可解析合法空容器及损坏样例,仍未做完整语料和原生对照;见[Zig 局部验收](../../../tests/acceptance/zig-grammar-candidate.md)。2026-09-29 后续增量:Objective-C 与 Solidity 从 CodeGraph 锁定的 `tree-sitter-wasms@0.1.13` 获取,依赖包完整性、两份原始 WASM、上游许可证及适配后字节均固定;Rust 将旧 `dylink` 元数据转为 `dylink.0`,离线加载、基本正反例及隔离 worker 候选观察通过。候选累计 7,已验收发行仍 0;完整语料、原生对照和公开 lint 路由仍缺,见[依赖 grammar 局部验收](../../../tests/acceptance/dependency-grammar-candidates.md)。后续增量:C、Go、JavaScript、Rust 的 CodeGraph 随仓 WASM 及上游版本标签许可证已固定,实测 Rust ABI、基础正反例和隔离 worker 候选状态;累计 11 份候选、21 种仍缺资产,见[主流语言局部验收](../../../tests/acceptance/mainstream-grammar-candidates.md)。本项及全量语言覆盖仍未完成。 +- [ ] 14.1 资产清单与来源。责任:adapters / 发布。规格:SP04。依赖:无。验收:固定 CodeGraph 来源提交、grammar 版本、许可证、SHA-256、ABI、语言/方言;缺来源、错散列和不兼容样本拒绝加载。进行中:已从固定 CodeGraph 提交复制 Java/Python/TypeScript/TSX WASM 与 MIT 许可证,清单和 Rust 校验拒绝来源/字节/声明 ABI 漂移;四份资产已由 Rust 离线加载并实测 ABI,Python 尚无 lint 路由;见[Python 资产局部验收](../../../tests/acceptance/python-grammar-asset-candidate.md);[局部证据](../../../tests/acceptance/grammar-asset-candidates.md)。新增与批准资产清单分离的[完整来源覆盖库存](../../../grammars/codegraph-coverage.json)及只读 `grammar status`:固定提交中的 30 份随仓 WASM 已逐字节核对,另两种依赖资产标为未固定,COBOL 的 16.4 MB 超出当前 8 MiB 加载限额;[覆盖验收](../../../tests/acceptance/codegraph-grammar-coverage.md)。其余 grammar 的上游许可证/版本、Rust 加载,以及所有候选的语言版本/方言、语料及可发行验收仍缺,不勾选。 Python 资产已接入可选源码构建的 `lint python` 局部候选路径,但版本/方言和发行验收仍缺;见[Python 兜底局部验收](../../../tests/acceptance/python-syntax-fallback-candidate.md)。 2026-09-29 增量:CodeGraph 来源更新至 `1072f82ce24db3d133258d30165cef6b74d108b2`,30/30 随仓字节与新提交一致。新增 Zig 第五份候选:保留新版原始 WASM、许可证和固定哈希;原始模块因 `__main_argc_argv` 不被 Rust `WasmStore` 接受,使用固定输入/输出散列的同签名导入适配后,可解析合法空容器及损坏样例,仍未做完整语料和原生对照;见[Zig 局部验收](../../../tests/acceptance/zig-grammar-candidate.md)。2026-09-29 后续增量:Objective-C 与 Solidity 从 CodeGraph 锁定的 `tree-sitter-wasms@0.1.13` 获取,依赖包完整性、两份原始 WASM、上游许可证及适配后字节均固定;Rust 将旧 `dylink` 元数据转为 `dylink.0`,离线加载、基本正反例及隔离 worker 候选观察通过。候选累计 7,已验收发行仍 0;完整语料、原生对照和公开 lint 路由仍缺,见[依赖 grammar 局部验收](../../../tests/acceptance/dependency-grammar-candidates.md)。后续增量:C、Go、JavaScript、Rust 的 CodeGraph 随仓 WASM 及上游版本标签许可证已固定,实测 Rust ABI、基础正反例和隔离 worker 候选状态;累计 11 份候选、21 种仍缺资产,见[主流语言局部验收](../../../tests/acceptance/mainstream-grammar-candidates.md)。再后续增量:C++/C#/Lua/Luau 的 CodeGraph 随仓 WASM 和上游许可证固定;C++ 真实 ABI 14(测试先按 15 失败后纠正),C# 的加载符号固定为 `c_sharp`,四份均由 Rust 离线加载并经隔离 worker 验证。累计 15 份候选、17 种仍缺资产,见[局部验收](../../../tests/acceptance/cpp-csharp-lua-luau-grammar-candidates.md)。本项及全量语言覆盖仍未完成。 - [ ] 14.2 Rust WASM 加载器。责任:runtime。规格:SP04,SP05。依赖:14.1。验收:支持固定资产离线加载;不依赖 Node 解析器、CodeGraph 或用户安装 tree-sitter-cli;通过有效/损坏/错 ABI 样本及 MSRV。进行中:可选 `wasm-precheck` 特性已通过 Java/Python/TypeScript/TSX Rust `WasmStore` 加载与反例测试,并由私有工作进程从 stdin 处理真实源码、父进程核对身份与恢复锚点,见[局部验收](../../../tests/acceptance/syntax-worker-candidate.md);本机无 Rust 1.85,MSRV 实编及正式 `lint/check` 接线尚缺。 - [ ] 14.3 进程资源隔离。责任:runtime。规格:SP05。依赖:14.2。验收:验证超时、内存、输出、取消与崩溃;损坏 grammar 不阻塞其他模块、不遗留进程。进行中:Unix 候选 worker 复用受控进程组内核,输入 1 MiB、输出 64 KiB,父进程有共同截止时间和取消;崩溃后代清理、输出洪泛、运行中取消及随后正常解析均增加真实子进程反例。Linux 2 GiB `RLIMIT_AS`、3 GiB 分配负例与 worker 故障隔离在 [Ubuntu CI](https://github.com/full-stack-plugins/codeguard/actions/runs/36478461118) 真实通过;Wasmtime 虚拟预留缩小。macOS 本机硬限制实测不支持,候选仍不具内存隔离权威;见[局部验收](../../../tests/acceptance/syntax-worker-candidate.md)。其它目标平台、损坏 grammar 隔离及正式调度仍缺,不勾选。 - [ ] 14.4 语言覆盖与源码映射。责任:adapters。规格:SP06。依赖:14.2。验收:识别 ERROR/MISSING,合并恢复节点;测试 Unicode、换行、嵌入语言、新语法和未知版本,不将不支持当源码违规。进行中:Rust 已提取两类原始节点,adapters 核对 UTF-8/CRLF 字节锚点并转换 Unicode 标量列;结构祖先归组保留并列错误,预算截断保持不完整;[局部证据](../../../tests/acceptance/syntax-recovery-candidate.md)。级联归并语料、版本/嵌入语言及原生对照仍缺。 @@ -1046,4 +1046,4 @@ TDD缺自动同步先RED。相关普通:build9、work sync15、next6,共30 - [ ] 14.16 Gemini CLI 实际对话接入。责任:plugin。规格:SP07,SP12。依赖:14.9,14.10。验收:独立验证真实 Gemini 对话反馈、去重、故障和权限边界,不借用其他宿主结果。 - [ ] 14.17 逐语言误报与性能评测。责任:评测/adapters。规格:SP06,SP12。依赖:14.3,14.4,14.11。验收:独立合法/非法 oracle、版本/方言语料、原生对照;分别报告误报、漏报、未知覆盖及冷暖启动/包体/内存;先实测再定预算。 - [ ] 14.18 打包兼容与分阶段发布验收。责任:发布/CLI。规格:SP04,SP11,SP12。依赖:14.12-14.17。验收:每个平台验证内置资产/许可证/散列和离线 npx;保持退出码、统一入口及旧报告读取;同步中英文示例;未验收语言/宿主仍标 gap。 -- [ ] 14.19 CodeGraph 32 种 grammar 全量接入与 Zig 误报回归。责任:adapters/runtime/CLI/发布。规格:SP01,SP04,SP06,SP11,SP12。依赖:14.1-14.18。验收:逐语言固定可再分发来源、许可证、原始和发行字节、真实 ABI、Rust worker 离线加载、合法/非法版本语料、原生工具对照、原生优先统一命令、任务与对话反馈、资源预算及发行包实装;覆盖 arkts/c/cfml/cfquery/cfscript/cobol/cpp/csharp/dart/erlang/go/java/javascript/kotlin/lua/luau/nix/objc/pascal/php/python/r/ruby/rust/scala/solidity/swift/terraform/tsx/typescript/vbnet/zig。当前十一份候选(C/Go/Java/JavaScript/Objective-C/Python/Rust/Solidity/TypeScript/TSX/Zig),已验收发行 0;COBOL 超出 8 MiB 上限,其他 21 种仍无资产清单和执行路由。C/Go/JavaScript/Rust 的固定来源、许可证、离线加载及基础正反例见[局部验收](../../../tests/acceptance/mainstream-grammar-candidates.md)。不得以 `grammar status` 库存、WASM 可加载或未验收候选替代原生 lint 或语言验收。 +- [ ] 14.19 CodeGraph 32 种 grammar 全量接入与 Zig 误报回归。责任:adapters/runtime/CLI/发布。规格:SP01,SP04,SP06,SP11,SP12。依赖:14.1-14.18。验收:逐语言固定可再分发来源、许可证、原始和发行字节、真实 ABI、Rust worker 离线加载、合法/非法版本语料、原生工具对照、原生优先统一命令、任务与对话反馈、资源预算及发行包实装;覆盖 arkts/c/cfml/cfquery/cfscript/cobol/cpp/csharp/dart/erlang/go/java/javascript/kotlin/lua/luau/nix/objc/pascal/php/python/r/ruby/rust/scala/solidity/swift/terraform/tsx/typescript/vbnet/zig。当前十五份候选(C/C++/C#/Go/Java/JavaScript/Lua/Luau/Objective-C/Python/Rust/Solidity/TypeScript/TSX/Zig),已验收发行 0;COBOL 超出 8 MiB 上限,其他 17 种仍无资产清单和执行路由。C++/C#/Lua/Luau 的固定来源、许可证、真实 ABI、离线加载及基础正反例见[局部验收](../../../tests/acceptance/cpp-csharp-lua-luau-grammar-candidates.md)。C/Go/JavaScript/Rust 的固定来源、许可证、离线加载及基础正反例见[局部验收](../../../tests/acceptance/mainstream-grammar-candidates.md)。不得以 `grammar status` 库存、WASM 可加载或未验收候选替代原生 lint 或语言验收。 diff --git a/schemas/grammar-asset-manifest.schema.json b/schemas/grammar-asset-manifest.schema.json index ed469b3e..bc7e477c 100644 --- a/schemas/grammar-asset-manifest.schema.json +++ b/schemas/grammar-asset-manifest.schema.json @@ -4,20 +4,18 @@ "title": "Pinned candidate Tree-sitter WASM assets; no CodeGuard syntax support claim", "type": "object", "additionalProperties": false, - "required": ["schema_version", "source_repository", "source_commit", "codegraph_license", "codegraph_license_sha256", "build_tool", "assets"], + "required": ["schema_version", "source_repository", "source_commit", "codegraph_license", "codegraph_license_sha256", "build_tool", "dependency_package_integrity", "dependency_package_license", "dependency_package_license_sha256", "assets"], "properties": { "schema_version": {"const": "1.0.0"}, "source_repository": {"const": "https://github.com/partme-ai/codegraph"}, "source_commit": {"$ref": "#/$defs/commit"}, "codegraph_license": {"const": "LICENSE.codegraph"}, "codegraph_license_sha256": {"$ref": "#/$defs/sha256"}, - "build_tool": {"const": "tree-sitter-cli 0.25.10 build --wasm"}, - "assets": { - "type": "array", - "minItems": 4, - "maxItems": 4, - "items": {"$ref": "#/$defs/asset"} - } + "build_tool": {"const": "tree-sitter-cli 0.25.10 build --wasm; Zig: tree-sitter-cli 0.27.0 generate --abi 15 + Zig 0.16.0 wasm32-wasi"}, + "dependency_package_integrity": {"type": "string", "pattern": "^tree-sitter-wasms@0\\.1\\.13 sha512-[A-Za-z0-9+/]+=*$"}, + "dependency_package_license": {"const": "LICENSE.tree-sitter-wasms"}, + "dependency_package_license_sha256": {"$ref": "#/$defs/sha256"}, + "assets": {"type": "array", "minItems": 1, "maxItems": 32, "items": {"$ref": "#/$defs/asset"}} }, "$defs": { "commit": {"type": "string", "pattern": "^[0-9a-f]{40}$"}, @@ -27,17 +25,20 @@ "additionalProperties": false, "required": ["language", "dialect", "grammar_repository", "grammar_commit", "grammar_version", "path", "sha256", "bytes", "license", "license_sha256", "abi_version", "codegraph_runtime", "codeguard_runtime_validation", "language_versions", "known_limitations", "release_status"], "properties": { - "language": {"enum": ["java", "python", "typescript", "tsx"]}, - "dialect": {"enum": ["java", "python", "typescript", "tsx"]}, - "grammar_repository": {"type": "string", "pattern": "^https://github.com/tree-sitter/tree-sitter-"}, + "language": {"enum": ["arkts", "c", "cfml", "cfquery", "cfscript", "cobol", "cpp", "csharp", "dart", "erlang", "go", "java", "javascript", "kotlin", "lua", "luau", "nix", "objc", "pascal", "php", "python", "r", "ruby", "rust", "scala", "solidity", "swift", "terraform", "tsx", "typescript", "vbnet", "zig"]}, + "dialect": {"type": "string", "minLength": 1}, + "loader_symbol": {"const": "c_sharp"}, + "grammar_repository": {"type": "string", "pattern": "^https://github\\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$"}, "grammar_commit": {"$ref": "#/$defs/commit"}, - "grammar_version": {"type": "string", "pattern": "^v[0-9]+\\.[0-9]+\\.[0-9]+$"}, - "path": {"enum": ["java/parser.wasm", "python/parser.wasm", "typescript/parser.wasm", "tsx/parser.wasm"]}, + "grammar_version": {"type": "string", "minLength": 1, "maxLength": 128}, + "path": {"type": "string", "pattern": "^[a-z0-9_]+/parser\\.wasm$"}, "sha256": {"$ref": "#/$defs/sha256"}, - "bytes": {"type": "integer", "minimum": 8, "maximum": 8388608}, - "license": {"enum": ["java/LICENSE", "python/LICENSE", "typescript/LICENSE"]}, + "bytes": {"type": "integer", "minimum": 8, "maximum": 33554432}, + "source_wasm": {"type": "string", "pattern": "^[a-z0-9_]+/source\\.wasm$"}, + "source_sha256": {"$ref": "#/$defs/sha256"}, + "license": {"type": "string", "pattern": "^[a-z0-9_]+/LICENSE$"}, "license_sha256": {"$ref": "#/$defs/sha256"}, - "abi_version": {"const": 14}, + "abi_version": {"type": "integer", "minimum": 13, "maximum": 15}, "codegraph_runtime": {"const": "web-tree-sitter 0.25.3"}, "codeguard_runtime_validation": {"const": "rust_loader_smoke_passed"}, "language_versions": {"type": "array", "maxItems": 0}, diff --git a/tests/acceptance/codegraph-grammar-coverage.md b/tests/acceptance/codegraph-grammar-coverage.md index 49292f05..df67008d 100644 --- a/tests/acceptance/codegraph-grammar-coverage.md +++ b/tests/acceptance/codegraph-grammar-coverage.md @@ -17,3 +17,5 @@ 2026-09-29 后续增量:Objective-C 与 Solidity 的依赖包原始字节、上游许可证及可复现的 Rust `dylink` 元数据适配现已入[候选清单](../../grammars/manifest.json);局部加载和隔离 worker 证据见[依赖 grammar 候选验收](dependency-grammar-candidates.md)。当前候选数 7,已验收发行仍为 0。上述 2/3/4/5 候选数是历史快照,旧的 `dependency_bytes_not_pinned` 状态也只适用于当时的库存。 后续增量:C、Go、JavaScript、Rust 的来源与 Rust worker 基础验证见[主流语言候选验收](mainstream-grammar-candidates.md)。当前候选资产 11/32,已验收发行仍为 0;之前 7 份候选仅是历史快照。 + +再后续增量:C++、C#、Lua、Luau 的来源与 Rust worker 基础验证见[四语种局部候选验收](cpp-csharp-lua-luau-grammar-candidates.md)。当前候选资产 15/32,已验收发行仍为 0;之前 11 份候选仅是历史快照。 diff --git a/tests/acceptance/cpp-csharp-lua-luau-grammar-candidates.md b/tests/acceptance/cpp-csharp-lua-luau-grammar-candidates.md new file mode 100644 index 00000000..c74ae5e5 --- /dev/null +++ b/tests/acceptance/cpp-csharp-lua-luau-grammar-candidates.md @@ -0,0 +1,11 @@ +# C++、C#、Lua、Luau grammar:局部候选验收 + +四份 WASM 来自固定 CodeGraph 提交 `1072f82ce24db3d133258d30165cef6b74d108b2`,原始字节与[覆盖库存](../../grammars/codegraph-coverage.json)的长度和 SHA-256 一致。[候选清单](../../grammars/manifest.json)固定上游标签提交、MIT 许可证字节、WASM 摘要及 Rust 实测 ABI:C++ 14、C# 15、Lua 15、Luau 14。C# 的公开语言 ID 是 `csharp`,WASM 导出符号是 `c_sharp`;清单显式固定 `loader_symbol`,篡改会被拒绝。 + +先把清单候选数断言从 11 改为 15,测试因尚未接入而失败。C++ 初次加载测试预期 ABI 15 时失败并报告实际为 14;更正声明后,四份资产均由 Rust `WasmStore` 离线加载,基础合法样例无恢复错误,未闭合或损坏样例有解析错误。隔离 worker 对合法样例均只返回 `incomplete`、`grammar_qualified=false`。 + +资产与 worker 变更的本地整轮验证:`cargo test --locked --workspace --all-features` 退出 0,182 组、1136 通过、0 失败、106 条有条件忽略;`cargo clippy --locked --workspace --all-targets --all-features -- -D warnings`、`cargo fmt --all -- --check` 及 `openspec validate introduce-rust-codeguard-cli --strict` 均通过。随后 schema 修正的定向测试为 6/6 通过;更新后整轮由 PR `gate` 复核。有条件忽略的原生工具用例不计入通过,也不作为原生对照证据。 + +补充发现与修复:早期 `schemas/grammar-asset-manifest.schema.json` 仍只接受四份候选,不能验证当前清单。现已更新为 32 种目标语言的封闭字段结构,并在 Rust 回归中检查当前清单所有字段和语言均被 schema 声明。使用本机既有 `/opt/anaconda3/bin/python3` 的 `jsonschema` 4.25.1 进行 Draft 2020-12 实际验证:15 份当前清单通过,伪造 `release_status=supported` 与篡改 C# `loader_symbol` 两个反例均被拒绝;未安装新依赖。此校验只证明清单协议一致,不证明 grammar 语法精度。 + +这些是窄范围资产与加载验证。C++ 宏/模板、C# 预处理、Lua/Luau 版本差异及嵌入语法均需独立语料和原生对照;误报/漏报、资源预算、公开 `lint` 路由和发行包安装未验收。原生 lint 仍是正式检查依据,零恢复节点不构成 clean 或任务关闭证据。