feat(policies): implement broker APIs and dotnet client#76
Merged
Vladyslav Nikonov (vnikonov-devolutions) merged 1 commit intoJun 29, 2026
Merged
Conversation
8763435 to
e0b9ed4
Compare
Copilot started reviewing on behalf of
Vladyslav Nikonov (vnikonov-devolutions)
June 29, 2026 16:38
View session
There was a problem hiding this comment.
Pull request overview
This PR introduces a cross-language (Rust + .NET) foundation for the NOW package broker/policy protocol: Rust becomes the schema source-of-truth (types + OpenAPI generation + fixtures), while .NET mirrors the DTOs and provides a transport-abstracted client with contract/fixture validation.
Changes:
- Add Rust
now-policy-api(canonical wire model + validation) andnow-policy-server-template(Axum facade, mock server, OpenAPI generator, shared fixtures). - Add .NET
Devolutions.Now.Policy.Api(DTOs/constants/compat) andDevolutions.Now.Policy.Client(client + named-pipe transport) plus a test suite validating against Rust-generated OpenAPI and shared samples. - Update solutions/workflows and apply small typo fixes in existing Rust/.NET code.
Reviewed changes
Copilot reviewed 100 out of 101 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| protocols/rust/now-proto-testsuite/tests/main.rs | Fix spelling in testsuite module docs. |
| protocols/rust/now-proto-pdu/src/message.rs | Fix spelling in message decoding comment. |
| protocols/dotnet/Devolutions.NowClient/src/NowClient.cs | Fix public API method name typo (ForceTerminate). |
| policies/rust/now-policy-server-template/tools/generate_openapi.rs | Add CLI to generate OpenAPI YAML from server template routes/types. |
| policies/rust/now-policy-server-template/tests/sample_documents.rs | Add Rust tests to validate sample documents and router/mock behavior. |
| policies/rust/now-policy-server-template/src/server.rs | Add server facade trait, Axum router, OpenAPI generator, and error→HTTP mapping. |
| policies/rust/now-policy-server-template/src/mock.rs | Add fixture-backed mock broker implementation for deterministic tests. |
| policies/rust/now-policy-server-template/src/lib.rs | Add crate entry point and re-exports for server template + API types. |
| policies/rust/now-policy-server-template/README.md | Document server template purpose, endpoints, fixtures, and OpenAPI generation. |
| policies/rust/now-policy-server-template/Cargo.toml | Add server template crate manifest (Axum/aide/schemars/serde deps). |
| policies/rust/now-policy-server-template/assets/samples/scenarios/extended.scenarios.json | Add extended scenario set fixture definitions. |
| policies/rust/now-policy-server-template/assets/samples/scenarios/baseline.scenarios.json | Add baseline scenario set fixture definitions. |
| policies/rust/now-policy-server-template/assets/samples/responses/winget-vscode-skiphash.denied.response.json | Add evaluation denied response fixture. |
| policies/rust/now-policy-server-template/assets/samples/responses/winget-vscode-install.allowed.response.json | Add evaluation allowed response fixture. |
| policies/rust/now-policy-server-template/assets/samples/responses/status-timeout.response.json | Add status timeout response fixture. |
| policies/rust/now-policy-server-template/assets/samples/responses/status-starting.response.json | Add status starting response fixture. |
| policies/rust/now-policy-server-template/assets/samples/responses/status-running.response.json | Add status running response fixture. |
| policies/rust/now-policy-server-template/assets/samples/responses/status-failed.response.json | Add status failed response fixture (incl. stdout/message). |
| policies/rust/now-policy-server-template/assets/samples/responses/status-completed.response.json | Add status completed response fixture (incl. details). |
| policies/rust/now-policy-server-template/assets/samples/responses/health-ready.response.json | Add health ready response fixture. |
| policies/rust/now-policy-server-template/assets/samples/responses/execution-winget-vscode-install.response.json | Add execution response fixture (submission + diagnostics). |
| policies/rust/now-policy-server-template/assets/samples/responses/capabilities.response.json | Add capabilities response fixture. |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-x86.request.json | Add package request fixture (x86 arch). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-winget-fonts.request.json | Add package request fixture (custom source). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-version-out-of-range.request.json | Add package request fixture (version out of range). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-version-in-range.request.json | Add package request fixture (version in range). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-update-in-range.request.json | Add package request fixture (update op). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-skiphash.request.json | Add package request fixture (skip hash). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-prerelease.request.json | Add package request fixture (prerelease). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-prepost.request.json | Add package request fixture (pre-operation command). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-msstore.request.json | Add package request fixture (msstore source). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-kill-before.request.json | Add package request fixture (kill-before list). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-interactive.request.json | Add package request fixture (interactive). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-install.request.yaml | Add YAML request fixture variant. |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-install.request.json | Add baseline JSON request fixture. |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-vscode-custom-param.request.json | Add package request fixture (custom parameters). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-unknown-install.request.json | Add package request fixture (unknown package). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-powertoys-install.request.json | Add package request fixture (PowerToys). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-git-uninstall.request.json | Add package request fixture (uninstall). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-git-custom-param-denied.request.json | Add package request fixture (custom param denied). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-git-custom-param-allowed.request.json | Add package request fixture (custom param allowed). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-git-custom-location-denied.request.json | Add package request fixture (custom location denied). |
| policies/rust/now-policy-server-template/assets/samples/requests/winget-git-custom-location-allowed.request.json | Add package request fixture (custom location allowed). |
| policies/rust/now-policy-server-template/assets/samples/requests/status-query-completed.request.json | Add status query request fixture. |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-version-out-of-range.request.json | Add PowerShell request fixture (version out of range). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-version-allowed.request.json | Add PowerShell request fixture (version allowed). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-update-currentuser.request.json | Add PowerShell request fixture (update). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-skipcheck.request.json | Add PowerShell request fixture (skip hash). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-prerelease.request.json | Add PowerShell request fixture (prerelease). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-poshtestgallery.request.json | Add PowerShell request fixture (untrusted source). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-currentuser.request.json | Add PowerShell request fixture (current user). |
| policies/rust/now-policy-server-template/assets/samples/requests/powershell-pester-allusers.request.json | Add PowerShell request fixture (all users). |
| policies/rust/now-policy-server-template/assets/samples/requests/missing-package-id.request.json | Add intentionally-invalid request fixture. |
| policies/rust/now-policy-api/src/status.rs | Add Rust status request/response DTOs. |
| policies/rust/now-policy-api/src/policy_compat.rs | Add Rust conversions between API model types and now-policy types. |
| policies/rust/now-policy-api/src/lib.rs | Add Rust canonical API model, fixed discriminators, and validated newtypes. |
| policies/rust/now-policy-api/src/health.rs | Add Rust health DTOs. |
| policies/rust/now-policy-api/src/execute.rs | Add Rust execute response DTOs. |
| policies/rust/now-policy-api/src/evaluate.rs | Add Rust evaluate response DTOs. |
| policies/rust/now-policy-api/src/enums.rs | Add Rust protocol enums. |
| policies/rust/now-policy-api/src/capabilities.rs | Add Rust capabilities DTOs. |
| policies/rust/now-policy-api/src/api.rs | Add Rust shared request/response/context/error DTOs. |
| policies/rust/now-policy-api/README.md | Document Rust API crate role and OpenAPI ownership. |
| policies/rust/now-policy-api/Cargo.toml | Add Rust API crate manifest (chrono/serde/schemars/semver/etc.). |
| policies/dotnet/Devolutions.Now.Policy.slnx | Add .NET API/client projects to solution. |
| policies/dotnet/Devolutions.Now.Policy.Model/README.md | Add .NET policy model package README. |
| policies/dotnet/Devolutions.Now.Policy.Model/Devolutions.Now.Policy.Model.csproj | Fix NuGet packing to include the correct README path. |
| policies/dotnet/Devolutions.Now.Policy.Client/README.md | Document .NET broker client architecture/usage/validation. |
| policies/dotnet/Devolutions.Now.Policy.Client/PackageOperationRequest.cs | Add client-facing request wrapper type. |
| policies/dotnet/Devolutions.Now.Policy.Client/OperationStatusQuery.cs | Add client-facing status query wrapper type. |
| policies/dotnet/Devolutions.Now.Policy.Client/NamedPipeBrokerTransport.cs | Add HTTP-over-named-pipe transport implementation. |
| policies/dotnet/Devolutions.Now.Policy.Client/IBrokerTransport.cs | Add transport abstraction interface. |
| policies/dotnet/Devolutions.Now.Policy.Client/Devolutions.Now.Policy.Client.csproj | Add .NET client project packaging/metadata and API dependency. |
| policies/dotnet/Devolutions.Now.Policy.Client/BrokerTransportResponse.cs | Add transport response DTO. |
| policies/dotnet/Devolutions.Now.Policy.Client/BrokerTransportRequest.cs | Add transport request DTO. |
| policies/dotnet/Devolutions.Now.Policy.Client/BrokerClientOptions.cs | Add broker client configuration surface. |
| policies/dotnet/Devolutions.Now.Policy.Client/BrokerClientException.cs | Add typed client exception for broker failures. |
| policies/dotnet/Devolutions.Now.Policy.Client/BrokerClientErrorKind.cs | Add error kind enum for client exception classification. |
| policies/dotnet/Devolutions.Now.Policy.Client/BrokerClient.cs | Add .NET broker client (capability caching, preflight, execute/wait, error mapping). |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/Usings.cs | Add global using for API DTOs in tests. |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/TestData.cs | Add test helper to load Rust OpenAPI + shared fixtures. |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/SchemaValidationTests.cs | Validate sample fixtures against OpenAPI schemas and API constants. |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/PolicyCompatibilityTests.cs | Validate enum compatibility conversions between policy model and broker API. |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/MetaModelTests.cs | Add DTO meta-behavior tests (discriminator handling, error response serialization). |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/DtoRoundTripTests.cs | Round-trip sample fixtures through DTOs and revalidate against schemas. |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/Devolutions.Now.Policy.Client.Tests.csproj | Add .NET client test project with schema/OpenAPI parsing dependencies. |
| policies/dotnet/Devolutions.Now.Policy.Client.Tests/BrokerClientTests.cs | Add behavioral tests for client metadata filling, preflight, and error typing. |
| policies/dotnet/Devolutions.Now.Policy.Api/StatusModels.cs | Add .NET status request/response DTOs with discriminator enforcement. |
| policies/dotnet/Devolutions.Now.Policy.Api/ResponseModels.cs | Add .NET evaluation/execution response DTOs and shared response types. |
| policies/dotnet/Devolutions.Now.Policy.Api/RequestModels.cs | Add .NET package request DTOs and shared request/context types. |
| policies/dotnet/Devolutions.Now.Policy.Api/README.md | Document .NET API DTO package role and OpenAPI relationship. |
| policies/dotnet/Devolutions.Now.Policy.Api/PolicyCompatibility.cs | Add .NET enum conversion helpers between API and policy model. |
| policies/dotnet/Devolutions.Now.Policy.Api/MetaModels.cs | Add .NET health/capabilities/error DTOs. |
| policies/dotnet/Devolutions.Now.Policy.Api/Enums.cs | Add .NET protocol enums with string-enum converters. |
| policies/dotnet/Devolutions.Now.Policy.Api/Devolutions.Now.Policy.Api.csproj | Add .NET API project packaging/metadata and model dependency. |
| policies/dotnet/Devolutions.Now.Policy.Api/BrokerJson.cs | Add canonical JSON serializer options for broker wire format. |
| policies/dotnet/Devolutions.Now.Policy.Api/BrokerApi.cs | Add .NET API constants + discriminator validation helper. |
| Cargo.toml | Update workspace lint configuration (remove string_to_string). |
| .github/workflows/nuget-publish.yml | Extend NuGet publish workflow to include new API/client libraries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Marc-André Moreau (mamoreau-devolutions)
approved these changes
Jun 29, 2026
e0b9ed4 to
e6359b7
Compare
5d343c5
into
master
9 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the package broker API/client foundation to
now-protoacross Rust and .NET.The main goal is to keep the broker protocol definition implementation-agnostic and transport-independent while making Rust the source of truth for schema/OpenAPI generation. .NET implementations and clients can then validate against the generated contract and stay synchronized with the Rust API model.
Architecture
Rust contract source of truth
policies/rust/now-policy-apidefines the canonical package broker wire model:RequestKind/ResponseKindmarker types that serialize as constant strings and validate discriminator values on deserialization;policies/rust/now-policy-api/openapi/now-policy-api.yaml.This crate intentionally contains no broker implementation. Its purpose is to describe the protocol shape, generate OpenAPI, and provide a stable Rust model for tests and server facades.
Rust server facade and mock template
policies/rust/now-policy-server-templateprovides the implementation boundary around the API crate:PackageBrokerServertrait as the server-side facade;This keeps real broker behavior out of
now-protowhile still allowing the API to be exercised end-to-end.Transport-independent message shape
The protocol now treats request/response identity as part of the body schema instead of HTTP metadata:
RequestKindandRequestVersionlive at the top level of request messages.ResponseKindandResponseVersionlive at the top level of response messages.This keeps the schema usable if the broker later moves away from HTTP-over-named-pipe to another transport.
.NET API package
policies/dotnet/Devolutions.Now.Policy.Apimirrors the Rust schema in C#:This package contains only API types and no transport/client execution logic.
.NET client package
policies/dotnet/Devolutions.Now.Policy.Clientcontains the actual client behavior:BrokerClientexposes high-level methods for health, capabilities, evaluate, execute, and operation status.BrokerClientOptionsis the single configuration entry point.IBrokerTransportabstracts transport so named pipes are only one implementation detail.NamedPipeBrokerTransporthandles the current HTTP-over-named-pipe transport.Test and fixture strategy
Shared Rust sample documents are used as contract fixtures for both Rust and .NET. The Rust server-template tests verify sample deserialization, mock broker behavior, and router/facade wiring. The .NET tests validate DTO schema compatibility, fixed discriminator handling, policy enum compatibility, fake transport behavior, capability preflight, error mapping, and client-generated request metadata.
Changes
now-policy-apiandnow-policy-server-templatecrates.Devolutions.Now.Policy.ApiandDevolutions.Now.Policy.Clientprojects.