diff --git a/.repository-projection.json b/.repository-projection.json index e053310..e495ab1 100644 --- a/.repository-projection.json +++ b/.repository-projection.json @@ -3,11 +3,11 @@ "projection": "capobara", "projectionSchemaVersion": 1, "sourceRepository": "dx-corp/mono", - "sourceSha": "3ccfbea716d8d52596980ca1f1f3b62166e7849d", + "sourceSha": "a971433d12b40d9042b3a64c2c074fa8fc398e69", "destinationRepository": "dx-corp/capobara", - "priorProjectedBase": "72796ef8e718acb181dbf0e101fe4b0af45b62e9", + "priorProjectedBase": "307384e1e96bf2ec22f2821e327f503ba226e9af", "definitionDigest": "7826c75cbd356dad6c867f2606ebde8b79ef4361353908cf33ada720034ec488", - "toolDigest": "898e8657d9153a2a51d7c283bf83bb3350b5d1e6", - "contentDigest": "e885e1248460736b96bfc794621e93051f8756668175e264adc51b6ce53ed7e3", + "toolDigest": "ff02edcbb40b0028af10ab01a101e918341f157a", + "contentDigest": "6a37cb0856ce05d920e8371504af2f233bfbdce0bf000d0c1e1ad1acfa90f07e", "publicationEligible": true } diff --git a/src/definition.rs b/src/definition.rs index 3ad52cb..269ce79 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -417,6 +417,28 @@ fn validate_definition_value( }); } + if name == "api" { + for (source, expected) in [ + ("proto", "deixicpublic/v1/sdk.proto"), + ("gen/openapi", "deixicpublic/v1/sdk.openapi.yaml"), + ] { + invalid( + mapping_fields + .iter() + .filter(|mapping| mapping.source == source) + .count() + == 1 + && mapping_fields.iter().any(|mapping| { + mapping.source == source + && mapping.include.len() == 1 + && mapping.include[0] == expected + && mapping.exclude.is_empty() + }), + format!("Public API {source} projection must contain only {expected}"), + )?; + } + } + if mode == "sdk-assembly-v1" { // Rule 10 let policy_inputs = sdk_inputs(name); diff --git a/src/modes/sdk_assembly.rs b/src/modes/sdk_assembly.rs index 1ce87bc..2578201 100644 --- a/src/modes/sdk_assembly.rs +++ b/src/modes/sdk_assembly.rs @@ -91,15 +91,11 @@ fn apply_transform(transform: Option, content: &[u8]) -> Result { - static DEPENDENCY: LazyLock = LazyLock::new(|| { - Regex::new(r#"(?m)^ "evalops-sdk[^"]+",\n"#).expect("static regex is valid") - }); contract( - DEPENDENCY.find_iter(&text).count() == 1, - "Python generated dependency declaration changed", + !text.contains("\"evalops-sdk"), + "Python package must not depend on the internal generated SDK", )?; - let without_dependency = DEPENDENCY.replace(&text, ""); - Ok(without_dependency + Ok(text .replace( "https://github.com/dx-corp/mono", "https://github.com/dx-corp/deixic-python", @@ -156,49 +152,25 @@ fn validate_closure(policy: &Policy, source_entries: &HashMap) -> } fn validate_python_closure(source_entries: &HashMap) -> Result<()> { + let protocol = source_text( + source_entries, + "sdk/deixic/python/src/deixicpublic/v1/sdk_pb2.py", + )?; + contract( + protocol.contains("deixicpublic.v1"), + "Python public protocol missing", + )?; static IMPORT: LazyLock = LazyLock::new(|| { - Regex::new(r"(?m)^from ([A-Za-z0-9_.]+) import ([A-Za-z0-9_]+_pb2)\b") + Regex::new(r"(?m)^from ([A-Za-z_][A-Za-z0-9_.]*) import .*_pb2") .expect("static regex is valid") }); - const PREFIX: &str = "gen/python/"; - let allowed: HashSet = policies::PYTHON_GENERATED_FILES - .iter() - .map(|path| format!("{PREFIX}{path}")) - .collect(); - let mut visited: HashSet = HashSet::new(); - let mut queue: Vec = vec![format!("{PREFIX}console/v1/console_pb2.py")]; - while let Some(path) = queue.pop() { - if visited.contains(&path) { - continue; - } + for caps in IMPORT.captures_iter(&protocol) { contract( - allowed.contains(&path), - format!("Python generated import escapes reviewed closure: {path}"), + caps[1].starts_with("google.protobuf"), + "Python protocol imports an unreviewed generated module", )?; - visited.insert(path.clone()); - let text = source_text(source_entries, &path)?; - for caps in IMPORT.captures_iter(&text) { - let package_name = &caps[1]; - let module_name = &caps[2]; - if package_name.starts_with("google.protobuf") { - continue; - } - let imported = format!( - "{PREFIX}{}/{module_name}.py", - package_name.replace('.', "/") - ); - contract( - allowed.contains(&imported), - format!("Python generated import escapes reviewed closure: {imported}"), - )?; - queue.push(imported); - } } - require_same_set( - &visited.into_iter().collect::>(), - &allowed.into_iter().collect::>(), - "Python generated dependency closure", - ) + Ok(()) } fn validate_typescript_closure(source_entries: &HashMap) -> Result<()> { @@ -209,18 +181,11 @@ fn validate_typescript_closure(source_entries: &HashMap) -> Resul "sdk/deixic/typescript/src/index.ts".to_string(), "sdk/deixic/typescript/src/tasks.ts".to_string(), ]; - let mut allowed: HashSet = build_roots.iter().cloned().collect(); - allowed.extend( - policies::NODE_SHARED_FILES - .iter() - .filter(|path| path.ends_with(".ts")) - .map(|path| (*path).to_string()), - ); - allowed.extend( - policies::TYPESCRIPT_GENERATED_FILES - .iter() - .map(|path| format!("gen/ts/{path}")), - ); + let allowed: HashSet = policies::NODE_PACKAGE_FILES + .iter() + .filter(|path| path.starts_with("src/")) + .map(|path| format!("sdk/deixic/typescript/{path}")) + .collect(); let mut visited: HashSet = HashSet::new(); let mut queue: Vec = build_roots.to_vec(); while let Some(path) = queue.pop() { @@ -283,8 +248,8 @@ fn validate_go_closure(source_entries: &HashMap) -> Result<()> { let mut visited_files: HashSet = HashSet::new(); let mut visited_packages: HashSet = HashSet::new(); let mut queue: Vec = vec![ - "deixic/v1".to_string(), - "deixic/v1/deixicv1connect".to_string(), + "deixicpublic/v1".to_string(), + "deixicpublic/v1/deixicpublicv1connect".to_string(), ]; while let Some(package_path) = queue.pop() { if visited_packages.contains(&package_path) { diff --git a/src/modes/sdk_assembly/policies.rs b/src/modes/sdk_assembly/policies.rs index 2079de9..2c60198 100644 --- a/src/modes/sdk_assembly/policies.rs +++ b/src/modes/sdk_assembly/policies.rs @@ -23,6 +23,10 @@ pub const PYTHON_SDK_FILES: &[&str] = &[ "src/deixic/examples/task_result.py", "src/deixic/examples/verify_test_journey.py", "src/deixic/py.typed", + "src/deixic/protocol.py", + "src/deixicpublic/__init__.py", + "src/deixicpublic/v1/__init__.py", + "src/deixicpublic/v1/sdk_pb2.py", "src/deixic/tasks.py", "src/deixic/transport.py", "tests/test_account_brief.py", @@ -37,33 +41,6 @@ pub const PYTHON_SDK_FILES: &[&str] = &[ // Generated protobuf/gRPC Python modules under `gen/python/`, copied into // `src/` (mirrors `PYTHON_GENERATED_FILES`). -pub const PYTHON_GENERATED_FILES: &[&str] = &[ - "agentruntime/v1/runtime_pb2.py", - "agents/v1/agents_pb2.py", - "buf/validate/validate_pb2.py", - "codex/v1/codex_pb2.py", - "common/v1/analytics_pb2.py", - "common/v1/authz_pb2.py", - "common/v1/classification_pb2.py", - "common/v1/delivery_pb2.py", - "common/v1/entity_pb2.py", - "common/v1/risk_pb2.py", - "common/v1/surface_pb2.py", - "connectors/v1/connectors_pb2.py", - "console/v1/console_pb2.py", - "evalops_platform/v1/platform_pb2.py", - "google/api/annotations_pb2.py", - "google/api/http_pb2.py", - "memory/v1/memory_pb2.py", - "meter/v1/meter_pb2.py", - "objectives/v1/objectives_pb2.py", - "orbcontrol/v1/orb_control_pb2.py", - "remoterunner/v1/remoterunner_pb2.py", - "toolexecution/v1/toolexecution_pb2.py", - "traces/v1/traces_pb2.py", - "vfs/v1/filesystem_pb2.py", -]; - // The reviewed Deixic Node package's own files (mirrors `NODE_PACKAGE_FILES`). pub const NODE_PACKAGE_FILES: &[&str] = &[ "CHANGELOG.md", @@ -78,6 +55,11 @@ pub const NODE_PACKAGE_FILES: &[&str] = &[ "scripts/smoke-packed-package.mjs", "src/index.ts", "src/tasks.ts", + "src/client.ts", + "src/errors.ts", + "src/accepted-turn.ts", + "src/app-context.ts", + "src/protocol.ts", "test/account-brief-result.test.mjs", "test/account-brief.test.mjs", "test/client.test.mjs", @@ -85,72 +67,9 @@ pub const NODE_PACKAGE_FILES: &[&str] = &[ "tsconfig.json", ]; -// index.ts is intentionally absent: the Deixic package imports this smaller -// reviewed helper closure directly instead of projecting the Maestro SDK. -pub const NODE_SHARED_FILES: &[&str] = &[ - "sdk/maestro/typescript/scripts/verify-descriptor-sources.mjs", - "sdk/maestro/typescript/src/accepted-turn.ts", - "sdk/maestro/typescript/src/app-context.ts", - "sdk/maestro/typescript/src/client.ts", - "sdk/maestro/typescript/src/errors.ts", -]; - -// Generated protobuf/gRPC TypeScript modules under `gen/ts/`, copied into -// place under the same relative path (mirrors `TYPESCRIPT_GENERATED_FILES`). -pub const TYPESCRIPT_GENERATED_FILES: &[&str] = &[ - "agentruntime/v1/runtime_pb.ts", - "agents/v1/agents_pb.ts", - "buf/validate/validate_pb.ts", - "codex/v1/codex_pb.ts", - "common/v1/analytics_pb.ts", - "common/v1/authz_pb.ts", - "common/v1/classification_pb.ts", - "common/v1/delivery_pb.ts", - "common/v1/entity_pb.ts", - "common/v1/risk_pb.ts", - "common/v1/surface_pb.ts", - "connectors/v1/connectors_pb.ts", - "console/v1/console_pb.ts", - "deixic/v1/deixic_pb.ts", - "google/api/annotations_pb.ts", - "google/api/http_pb.ts", - "memory/v1/memory_pb.ts", - "meter/v1/meter_pb.ts", - "objectives/v1/objectives_pb.ts", - "orbcontrol/v1/orb_control_pb.ts", - "platform/v1/platform_pb.ts", - "remoterunner/v1/remoterunner_pb.ts", - "toolexecution/v1/toolexecution_pb.ts", - "traces/v1/traces_pb.ts", - "vfs/v1/filesystem_pb.ts", -]; - -// Generated protobuf/gRPC Go modules under `gen/go/`, copied into place under -// the same relative path (mirrors `GO_GENERATED_FILES`). pub const GO_GENERATED_FILES: &[&str] = &[ - "agentruntime/v1/runtime.pb.go", - "agents/v1/agents.pb.go", - "codex/v1/codex.pb.go", - "common/v1/analytics.pb.go", - "common/v1/authz.pb.go", - "common/v1/classification.pb.go", - "common/v1/delivery.pb.go", - "common/v1/entity.pb.go", - "common/v1/risk.pb.go", - "common/v1/surface.pb.go", - "connectors/v1/connectors.pb.go", - "console/v1/console.pb.go", - "deixic/v1/deixic.pb.go", - "deixic/v1/deixicv1connect/deixic.connect.go", - "memory/v1/memory.pb.go", - "meter/v1/meter.pb.go", - "objectives/v1/objectives.pb.go", - "orbcontrol/v1/orb_control.pb.go", - "platform/v1/platform.pb.go", - "remoterunner/v1/remoterunner.pb.go", - "toolexecution/v1/toolexecution.pb.go", - "traces/v1/traces.pb.go", - "vfs/v1/filesystem.pb.go", + "deixicpublic/v1/sdk.pb.go", + "deixicpublic/v1/deixicpublicv1connect/sdk.connect.go", ]; /// A byte-for-byte transform applied to one copy's content, keyed by the @@ -208,7 +127,7 @@ fn copy( } fn python_copies() -> Vec { - let mut copies: Vec = PYTHON_SDK_FILES + let copies: Vec = PYTHON_SDK_FILES .iter() .map(|path| { copy( @@ -218,16 +137,11 @@ fn python_copies() -> Vec { ) }) .collect(); - copies.extend( - PYTHON_GENERATED_FILES - .iter() - .map(|path| copy(format!("gen/python/{path}"), format!("src/{path}"), None)), - ); copies } fn node_copies() -> Vec { - let mut copies: Vec = NODE_PACKAGE_FILES + let copies: Vec = NODE_PACKAGE_FILES .iter() .map(|path| { let full = format!("sdk/deixic/typescript/{path}"); @@ -238,15 +152,6 @@ fn node_copies() -> Vec { ) }) .collect(); - copies.extend( - NODE_SHARED_FILES - .iter() - .map(|path| copy((*path).to_string(), (*path).to_string(), None)), - ); - copies.extend(TYPESCRIPT_GENERATED_FILES.iter().map(|path| { - let full = format!("gen/ts/{path}"); - copy(full.clone(), full, None) - })); copies } @@ -256,12 +161,11 @@ fn go_copies() -> Vec { copy("sdk/deixic/python/LICENSE", "LICENSE", None), copy( "sdk/deixic/go/deixic_connect_test.go.in", - "deixic/v1/deixicv1connect/projection_test.go", + "deixicpublic/v1/deixicpublicv1connect/projection_test.go", None, ), - copy("gen/go/CHANGELOG.md", "CHANGELOG.md", None), - copy("gen/go/go.mod", "go.mod", Some(Transform::GoModule)), - copy("gen/go/go.sum", "go.sum", None), + copy("sdk/deixic/go/go.mod", "go.mod", None), + copy("sdk/deixic/go/go.sum", "go.sum", None), ]; copies.extend(GO_GENERATED_FILES.iter().map(|path| { copy( @@ -314,12 +218,7 @@ static POLICIES: LazyLock> = LazyLock::new(|| { "deixic-node", node_copies(), Closure::TypescriptCompiledImportsV1, - &[ - "gen/ts/**", - "sdk/deixic/typescript/**", - "sdk/maestro/typescript/scripts/verify-descriptor-sources.mjs", - "sdk/maestro/typescript/src/**", - ], + &["sdk/deixic/typescript/**"], ), make_policy( "deixic-go", @@ -329,24 +228,9 @@ static POLICIES: LazyLock> = LazyLock::new(|| { "CHANGELOG.md", "LICENSE", "README.md", - "agentruntime/**", - "agents/**", - "codex/**", - "common/**", - "connectors/**", - "console/**", - "deixic/**", + "deixicpublic/**", "go.mod", "go.sum", - "memory/**", - "meter/**", - "objectives/**", - "orbcontrol/**", - "platform/**", - "remoterunner/**", - "toolexecution/**", - "traces/**", - "vfs/**", ], ), ] diff --git a/tests/fixtures/sdk-assembly.json b/tests/fixtures/sdk-assembly.json index 2cb33f4..735dd99 100644 --- a/tests/fixtures/sdk-assembly.json +++ b/tests/fixtures/sdk-assembly.json @@ -6,19 +6,6 @@ "LICENSE", "README.md", "pyproject.toml", - "src/agentruntime/v1/runtime_pb2.py", - "src/agents/v1/agents_pb2.py", - "src/buf/validate/validate_pb2.py", - "src/codex/v1/codex_pb2.py", - "src/common/v1/analytics_pb2.py", - "src/common/v1/authz_pb2.py", - "src/common/v1/classification_pb2.py", - "src/common/v1/delivery_pb2.py", - "src/common/v1/entity_pb2.py", - "src/common/v1/risk_pb2.py", - "src/common/v1/surface_pb2.py", - "src/connectors/v1/connectors_pb2.py", - "src/console/v1/console_pb2.py", "src/deixic/__init__.py", "src/deixic/auth.py", "src/deixic/client.py", @@ -28,20 +15,13 @@ "src/deixic/examples/account_brief_result.py", "src/deixic/examples/task_result.py", "src/deixic/examples/verify_test_journey.py", + "src/deixic/protocol.py", "src/deixic/py.typed", "src/deixic/tasks.py", "src/deixic/transport.py", - "src/evalops_platform/v1/platform_pb2.py", - "src/google/api/annotations_pb2.py", - "src/google/api/http_pb2.py", - "src/memory/v1/memory_pb2.py", - "src/meter/v1/meter_pb2.py", - "src/objectives/v1/objectives_pb2.py", - "src/orbcontrol/v1/orb_control_pb2.py", - "src/remoterunner/v1/remoterunner_pb2.py", - "src/toolexecution/v1/toolexecution_pb2.py", - "src/traces/v1/traces_pb2.py", - "src/vfs/v1/filesystem_pb2.py", + "src/deixicpublic/__init__.py", + "src/deixicpublic/v1/__init__.py", + "src/deixicpublic/v1/sdk_pb2.py", "tests/test_account_brief.py", "tests/test_account_brief_application.py", "tests/test_client.py", @@ -52,31 +32,6 @@ "tests/test_test_journey.py" ], "deixic-node": [ - "gen/ts/agentruntime/v1/runtime_pb.ts", - "gen/ts/agents/v1/agents_pb.ts", - "gen/ts/buf/validate/validate_pb.ts", - "gen/ts/codex/v1/codex_pb.ts", - "gen/ts/common/v1/analytics_pb.ts", - "gen/ts/common/v1/authz_pb.ts", - "gen/ts/common/v1/classification_pb.ts", - "gen/ts/common/v1/delivery_pb.ts", - "gen/ts/common/v1/entity_pb.ts", - "gen/ts/common/v1/risk_pb.ts", - "gen/ts/common/v1/surface_pb.ts", - "gen/ts/connectors/v1/connectors_pb.ts", - "gen/ts/console/v1/console_pb.ts", - "gen/ts/deixic/v1/deixic_pb.ts", - "gen/ts/google/api/annotations_pb.ts", - "gen/ts/google/api/http_pb.ts", - "gen/ts/memory/v1/memory_pb.ts", - "gen/ts/meter/v1/meter_pb.ts", - "gen/ts/objectives/v1/objectives_pb.ts", - "gen/ts/orbcontrol/v1/orb_control_pb.ts", - "gen/ts/platform/v1/platform_pb.ts", - "gen/ts/remoterunner/v1/remoterunner_pb.ts", - "gen/ts/toolexecution/v1/toolexecution_pb.ts", - "gen/ts/traces/v1/traces_pb.ts", - "gen/ts/vfs/v1/filesystem_pb.ts", "sdk/deixic/typescript/CHANGELOG.md", "sdk/deixic/typescript/LICENSE", "sdk/deixic/typescript/README.md", @@ -87,49 +42,27 @@ "sdk/deixic/typescript/package.json", "sdk/deixic/typescript/scripts/check-package-exports.mjs", "sdk/deixic/typescript/scripts/smoke-packed-package.mjs", + "sdk/deixic/typescript/src/accepted-turn.ts", + "sdk/deixic/typescript/src/app-context.ts", + "sdk/deixic/typescript/src/client.ts", + "sdk/deixic/typescript/src/errors.ts", "sdk/deixic/typescript/src/index.ts", + "sdk/deixic/typescript/src/protocol.ts", "sdk/deixic/typescript/src/tasks.ts", "sdk/deixic/typescript/test/account-brief-result.test.mjs", "sdk/deixic/typescript/test/account-brief.test.mjs", "sdk/deixic/typescript/test/client.test.mjs", "sdk/deixic/typescript/test/tasks.test.mjs", - "sdk/deixic/typescript/tsconfig.json", - "sdk/maestro/typescript/scripts/verify-descriptor-sources.mjs", - "sdk/maestro/typescript/src/accepted-turn.ts", - "sdk/maestro/typescript/src/app-context.ts", - "sdk/maestro/typescript/src/client.ts", - "sdk/maestro/typescript/src/errors.ts" + "sdk/deixic/typescript/tsconfig.json" ], "deixic-go": [ - "CHANGELOG.md", "LICENSE", "README.md", - "agentruntime/v1/runtime.pb.go", - "agents/v1/agents.pb.go", - "codex/v1/codex.pb.go", - "common/v1/analytics.pb.go", - "common/v1/authz.pb.go", - "common/v1/classification.pb.go", - "common/v1/delivery.pb.go", - "common/v1/entity.pb.go", - "common/v1/risk.pb.go", - "common/v1/surface.pb.go", - "connectors/v1/connectors.pb.go", - "console/v1/console.pb.go", - "deixic/v1/deixic.pb.go", - "deixic/v1/deixicv1connect/deixic.connect.go", - "deixic/v1/deixicv1connect/projection_test.go", + "deixicpublic/v1/deixicpublicv1connect/projection_test.go", + "deixicpublic/v1/deixicpublicv1connect/sdk.connect.go", + "deixicpublic/v1/sdk.pb.go", "go.mod", - "go.sum", - "memory/v1/memory.pb.go", - "meter/v1/meter.pb.go", - "objectives/v1/objectives.pb.go", - "orbcontrol/v1/orb_control.pb.go", - "platform/v1/platform.pb.go", - "remoterunner/v1/remoterunner.pb.go", - "toolexecution/v1/toolexecution.pb.go", - "traces/v1/traces.pb.go", - "vfs/v1/filesystem.pb.go" + "go.sum" ] }, "executables": { diff --git a/tests/sdk_assembly.rs b/tests/sdk_assembly.rs index 84d8d7b..c181e9b 100644 --- a/tests/sdk_assembly.rs +++ b/tests/sdk_assembly.rs @@ -72,7 +72,12 @@ fn relative_specifier(from_file: &str, to_file: &str) -> String { let mut segments: Vec = (0..ups).map(|_| "..".to_string()).collect(); segments.extend(to_parts[common..].iter().map(|s| s.to_string())); segments.push(to_name.to_string()); - segments.join("/") + let result = segments.join("/"); + if ups == 0 { + format!("./{result}") + } else { + result + } } /// Swaps a `.ts` specifier for the `.js` one the real compiled output (and @@ -84,28 +89,12 @@ fn js_specifier(ts_path: &str) -> String { } } -fn python_package_and_module(generated_path: &str) -> (String, String) { - let without_ext = generated_path.strip_suffix(".py").unwrap(); - match without_ext.rsplit_once('/') { - Some((dir, module)) => (dir.replace('/', "."), module.to_string()), - None => (String::new(), without_ext.to_string()), - } -} - -fn go_package_of(path: &str) -> String { - match path.rfind('/') { - Some(idx) => path[..idx].to_string(), - None => String::new(), - } -} - const PYPROJECT_TOML: &str = concat!( "[project]\n", "name = \"deixic\"\n", "version = \"0.1.0\"\n", "dependencies = [\n", " \"httpx>=0.27\",\n", - " \"evalops-sdk-core==1.2.3\",\n", "]\n", "\n", "[project.urls]\n", @@ -123,7 +112,7 @@ const PACKAGE_JSON: &str = concat!( "}\n", ); -const GO_MOD: &str = "module github.com/evalops/platform/gen/go\n\ngo 1.21\n"; +const GO_MOD: &str = "module github.com/dx-corp/deixic-go\n\ngo 1.26.0\n"; /// Builds a tempdir snapshot containing every input every policy names, /// shaped so all three closures pass. Reused by every test below except the @@ -147,22 +136,11 @@ fn populate_snapshot(root: &Path) { write(root, &full, format!("# {path}\n").as_bytes()); } } - for path in policies::PYTHON_GENERATED_FILES { - let full = format!("gen/python/{path}"); - if *path == "console/v1/console_pb2.py" { - let mut content = String::from("# generated console module\n"); - for other in policies::PYTHON_GENERATED_FILES { - if *other == *path { - continue; - } - let (package, module) = python_package_and_module(other); - content.push_str(&format!("from {package} import {module}\n")); - } - write(root, &full, content.as_bytes()); - } else { - write(root, &full, b"# generated\n"); - } - } + write( + root, + "sdk/deixic/python/src/deixicpublic/v1/sdk_pb2.py", + b"# deixicpublic.v1\n", + ); // ---- Node / TypeScript ---- let index_path = "sdk/deixic/typescript/src/index.ts"; @@ -180,55 +158,31 @@ fn populate_snapshot(root: &Path) { } } let mut index_content = String::new(); - for shared in policies::NODE_SHARED_FILES + for path in policies::NODE_PACKAGE_FILES .iter() - .filter(|path| path.ends_with(".ts")) + .filter(|path| path.starts_with("src/") && **path != "src/index.ts") { - let spec = js_specifier(&relative_specifier(index_path, shared)); - index_content.push_str(&format!("export * from \"{spec}\";\n")); - } - for generated in policies::TYPESCRIPT_GENERATED_FILES { - let full = format!("gen/ts/{generated}"); + let full = format!("sdk/deixic/typescript/{path}"); let spec = js_specifier(&relative_specifier(index_path, &full)); index_content.push_str(&format!("export * from \"{spec}\";\n")); } write(root, index_path, index_content.as_bytes()); - for path in policies::NODE_SHARED_FILES { - write(root, path, format!("// {path}\n").as_bytes()); - } - for path in policies::TYPESCRIPT_GENERATED_FILES { - write(root, &format!("gen/ts/{path}"), b"// generated\n"); - } // ---- Go ---- write(root, "sdk/deixic/go/README.md", b"# deixic-go\n"); write( root, "sdk/deixic/go/deixic_connect_test.go.in", - b"package deixicv1connect_test\n\nfunc TestProjection(t *testing.T) {}\n", + b"package deixicpublicv1connect_test\n\nfunc TestProjection(t *testing.T) {}\n", ); write(root, "gen/go/CHANGELOG.md", b"# changelog\n"); - write(root, "gen/go/go.mod", GO_MOD.as_bytes()); - write(root, "gen/go/go.sum", b"\n"); + write(root, "sdk/deixic/go/go.mod", GO_MOD.as_bytes()); + write(root, "sdk/deixic/go/go.sum", b"\n"); - let hub_package: &str = "deixic/v1"; - let mut other_packages: BTreeSet = policies::GO_GENERATED_FILES - .iter() - .map(|path| go_package_of(path)) - .collect(); - other_packages.remove(hub_package); - other_packages.remove("deixic/v1/deixicv1connect"); - let mut import_block = String::new(); - for package in &other_packages { - import_block.push_str(&format!( - "\t\"github.com/evalops/platform/gen/go/{package}\"\n" - )); - } - let deixic_pb_go = - format!("package deixicv1\n\nimport (\n{import_block})\n\ntype Placeholder struct{{}}\n"); + let deixic_pb_go = "package deixicpublicv1\n\ntype Placeholder struct{}\n"; for path in policies::GO_GENERATED_FILES { let full = format!("gen/go/{path}"); - if *path == "deixic/v1/deixic.pb.go" { + if *path == "deixicpublic/v1/sdk.pb.go" { write(root, &full, deixic_pb_go.as_bytes()); } else { write(root, &full, b"// generated\n"); @@ -340,11 +294,10 @@ fn language_specific_assembly_removes_unpublished_and_mono_only_identities() { .into_owned(); assert!(package_json.contains("github.com/dx-corp/deixic-node")); assert!( - node.entries + !node + .entries .keys() - .filter(|path| path.starts_with("sdk/maestro/")) - .all(|path| path.contains("/typescript/src/") - || path.ends_with("verify-descriptor-sources.mjs")) + .any(|path| path.starts_with("sdk/maestro/")) ); assert!( !node @@ -367,7 +320,7 @@ fn language_specific_assembly_removes_unpublished_and_mono_only_identities() { ) .unwrap(); assert_eq!( - go.entries["deixic/v1/deixicv1connect/projection_test.go"].content, + go.entries["deixicpublic/v1/deixicpublicv1connect/projection_test.go"].content, go_test_template ); let go_mod = String::from_utf8_lossy(&go.entries["go.mod"].content).into_owned(); @@ -387,7 +340,9 @@ fn language_specific_assembly_removes_unpublished_and_mono_only_identities() { #[test] fn generated_dependency_closure_fails_closed_when_an_import_escapes() { let snapshot = build_snapshot(); - let console_path = snapshot.path().join("gen/python/console/v1/console_pb2.py"); + let console_path = snapshot + .path() + .join("sdk/deixic/python/src/deixicpublic/v1/sdk_pb2.py"); let mut content = std::fs::read_to_string(&console_path).unwrap(); content.push_str("from private.v1 import staff_pb2\n"); std::fs::write(&console_path, content).unwrap(); @@ -395,7 +350,7 @@ fn generated_dependency_closure_fails_closed_when_an_import_escapes() { let err = sdk_assembly::assemble(snapshot.path(), "deixic-python").unwrap_err(); assert_eq!( err.to_string(), - "Python generated import escapes reviewed closure: gen/python/private/v1/staff_pb2.py" + "Python protocol imports an unreviewed generated module" ); } diff --git a/tests/support/mod.rs b/tests/support/mod.rs index 6171c4a..77e4b30 100644 --- a/tests/support/mod.rs +++ b/tests/support/mod.rs @@ -82,7 +82,6 @@ pub fn populate_python_snapshot(root: &Path) { "version = \"0.1.0\"\n", "dependencies = [\n", " \"httpx>=0.27\",\n", - " \"evalops-sdk-core==1.2.3\",\n", "]\n", "\n", "[project.urls]\n", @@ -95,14 +94,6 @@ pub fn populate_python_snapshot(root: &Path) { std::fs::write(&full, contents).unwrap(); } - fn package_and_module(generated_path: &str) -> (String, String) { - let without_ext = generated_path.strip_suffix(".py").unwrap(); - match without_ext.rsplit_once('/') { - Some((dir, module)) => (dir.replace('/', "."), module.to_string()), - None => (String::new(), without_ext.to_string()), - } - } - for path in policies::PYTHON_SDK_FILES { let full = format!("sdk/deixic/python/{path}"); if *path == "pyproject.toml" { @@ -111,22 +102,11 @@ pub fn populate_python_snapshot(root: &Path) { write(root, &full, format!("# {path}\n").as_bytes()); } } - for path in policies::PYTHON_GENERATED_FILES { - let full = format!("gen/python/{path}"); - if *path == "console/v1/console_pb2.py" { - let mut content = String::from("# generated console module\n"); - for other in policies::PYTHON_GENERATED_FILES { - if *other == *path { - continue; - } - let (package, module) = package_and_module(other); - content.push_str(&format!("from {package} import {module}\n")); - } - write(root, &full, content.as_bytes()); - } else { - write(root, &full, b"# generated\n"); - } - } + write( + root, + "sdk/deixic/python/src/deixicpublic/v1/sdk_pb2.py", + b"# deixicpublic.v1\n", + ); } // ---------------------------------------------------------------------