Skip to content

feat: add active package policy inspection contract - #93

Merged
Benoît Cortier (CBenoit) merged 12 commits into
masterfrom
cbenoit-plan-policy-contract
Aug 28, 2026
Merged

feat: add active package policy inspection contract#93
Benoît Cortier (CBenoit) merged 12 commits into
masterfrom
cbenoit-plan-policy-contract

Conversation

@CBenoit

@CBenoit Benoît Cortier (CBenoit) commented Aug 17, 2026

Copy link
Copy Markdown
Member
  • add canonical GET /v1/policy support across the Rust server contract, generated OpenAPI, C# DTOs, and BrokerClient.GetPolicy(CancellationToken)
  • return the existing canonical PolicyDocument inside a versioned PolicyResponse, with structured 404 NotFound behavior when no active policy is configured
  • make policy inspection unconditional: remove policy-compat and its cross-model conversion impls, and keep runtime mapping ownership in broker implementations
  • name the required Rust server accessor active_policy, leaving clear room for a future explicit replace_policy operation backed by a separate policy-store abstraction
  • harden C# successful-response validation for required/null fields, collection elements, unknown members, and canonical enum casing
  • preserve existing OpenAPI component names by namespacing colliding embedded policy components as PolicyModel…
  • run workspace Rust tests and Clippy with all features through the standard xtask commands

API changes

Rust

  • now-policy-api adds public PolicyResponse and PolicyResponseKind; now-policy is now a normal dependency because PolicyDocument is part of the permanent wire contract

  • PackageBrokerServer adds the required method:

    async fn active_policy(&self) -> Result<PolicyResponse, ErrorResponse>;
  • now-policy-server-template registers the route unconditionally and extends its mock with policy response/error builders

  • policy-compat and its From/TryFrom conversions are removed

C#

  • Devolutions.Now.Policy.Api adds PolicyResponse, embedding Devolutions.Now.Policy.Model.PolicyDocument
  • Devolutions.Now.Policy.Client adds GetPolicy(CancellationToken) with strict validation of successful response bodies
  • policy-model deserialization now enforces required members, non-null collection elements, and canonical enum casing

HTTP

  • adds read-only GET /v1/policy
  • 200: PolicyResponse
  • 404: structured ErrorResponse when no active policy is configured
  • other failures use the existing ErrorResponse contract
  • no policy mutation endpoint is introduced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 17, 2026 17:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a feature-gated active-policy inspection contract across Rust, OpenAPI, and .NET.

Changes:

  • Adds GET /v1/policy, DTOs, routing, mocks, and structured errors.
  • Adds .NET serialization and client support.
  • Adds shared fixtures, tests, CI coverage, and documentation.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
xtask/src/rust.rs Tests and lints policy features.
policies/rust/now-policy-server-template/tests/sample_documents.rs Tests policy fixtures and routing.
policies/rust/now-policy-server-template/src/server.rs Implements route and OpenAPI schema registration.
policies/rust/now-policy-server-template/src/mock.rs Adds configurable policy responses.
policies/rust/now-policy-server-template/README.md Documents policy endpoint support.
policies/rust/now-policy-server-template/Cargo.toml Requires policy feature for generation.
policies/rust/now-policy-server-template/assets/samples/responses/policy.response.json Adds shared response fixture.
policies/rust/now-policy-api/src/policy.rs Defines Rust policy response DTO.
policies/rust/now-policy-api/src/lib.rs Exports policy contract types.
policies/rust/now-policy-api/README.md Documents the Rust DTO.
policies/rust/now-policy-api/openapi/now-policy-api.yaml Publishes endpoint and schemas.
policies/dotnet/Devolutions.Now.Policy.Client/README.md Documents client behavior.
policies/dotnet/Devolutions.Now.Policy.Client/BrokerClient.cs Adds GetPolicy.
policies/dotnet/Devolutions.Now.Policy.Client.Tests/TestData.cs Discovers policy fixtures.
policies/dotnet/Devolutions.Now.Policy.Client.Tests/SchemaValidationTests.cs Validates policy schemas.
policies/dotnet/Devolutions.Now.Policy.Client.Tests/MetaModelTests.cs Tests response discriminator validation.
policies/dotnet/Devolutions.Now.Policy.Client.Tests/DtoRoundTripTests.cs Tests DTO round trips.
policies/dotnet/Devolutions.Now.Policy.Client.Tests/BrokerClientTests.cs Tests requests, errors, and cancellation.
policies/dotnet/Devolutions.Now.Policy.Api/ResponseModels.cs Defines .NET policy response DTO.
policies/dotnet/Devolutions.Now.Policy.Api/README.md Documents active-policy DTOs.
policies/dotnet/Devolutions.Now.Policy.Api/BrokerJson.cs Adds source-generated serialization.
policies/dotnet/Devolutions.Now.Policy.Api/BrokerApi.cs Adds policy response discriminator.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread policies/rust/now-policy-server-template/tests/sample_documents.rs Outdated
Comment thread policies/dotnet/Devolutions.Now.Policy.Api/ResponseModels.cs
Comment thread policies/rust/now-policy-server-template/README.md Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Suppressed comments (2)

policies/dotnet/Devolutions.Now.Policy.Client/README.md:48

  • The method returns PolicyResponse, not PolicyDocument; the policy document is its Policy property. Describing the wrapper accurately prevents callers from expecting the wrong public return type.
- `GetPolicy` sends `GET /v1/policy` and returns the active parsed `PolicyDocument` after strict source-generated validation of the successful response.

policies/dotnet/Devolutions.Now.Policy.Api/BrokerJson.cs:124

  • RespectNullableAnnotations does not validate nullability of collection elements. GetPolicy therefore still accepts contract-invalid payloads such as "Rules":[null] or "Sources":[null], placing nulls into non-nullable lists even though Rust and the OpenAPI schema reject them; consumers can then hit null-reference failures. Add element-level converters or post-deserialization validation (with coverage) before returning PolicyResponse.
    RespectNullableAnnotations = true,

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Benoît Cortier (CBenoit) added a commit to Devolutions/devolutions-gateway that referenced this pull request Aug 18, 2026
Return a generic policy-unavailable message so clients cannot infer
whether the active policy is file-backed, missing, or corrupt.

Issue: Devolutions/now-libraries#93

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve the schemars 0.9 OpenAPI schema registration conflict while preserving namespaced policy components.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remove the policy-compat feature and conversion implementations. The API now composes the canonical policy document directly, while runtime adapters remain owned by broker implementations.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Rename the server trait method to active_policy so it remains distinct from a future replace_policy operation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.

@CBenoit Benoît Cortier (CBenoit) changed the title Add active package policy inspection contract feat: add active package policy inspection contract Aug 28, 2026
@CBenoit
Benoît Cortier (CBenoit) enabled auto-merge (squash) August 28, 2026 12:54
@CBenoit
Benoît Cortier (CBenoit) merged commit cd5a6e9 into master Aug 28, 2026
10 checks passed
@CBenoit
Benoît Cortier (CBenoit) deleted the cbenoit-plan-policy-contract branch August 28, 2026 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants