feat!: add package policy management contract - #99
Open
Benoît Cortier (CBenoit) wants to merge 4 commits into
Open
feat!: add package policy management contract#99Benoît Cortier (CBenoit) wants to merge 4 commits into
Benoît Cortier (CBenoit) wants to merge 4 commits into
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds cross-language package-policy management contracts, including draft validation, optimistic replacement, management snapshots, and JSON-only policy models.
Changes:
- Adds Rust and .NET management APIs, routes, DTOs, validation, and clients.
- Introduces editable policy drafts and removes YAML policy parsing.
- Adds fixtures and stricter boolean-match validation.
Reviewed changes
Copilot reviewed 52 out of 53 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
policies/test-data/package-broker/scenarios/baseline.scenarios.json |
Removes YAML-policy scenarios. |
policies/test-data/package-broker/responses/policy-validation.valid.response.json |
Adds valid-validation fixture. |
policies/test-data/package-broker/responses/policy-validation.invalid.response.json |
Adds invalid-validation fixture. |
policies/test-data/package-broker/responses/policy-stale-token.error.json |
Adds stale-token error fixture. |
policies/test-data/package-broker/responses/policy-replacement.response.json |
Adds replacement response fixture. |
policies/test-data/package-broker/responses/policy-management.missing.response.json |
Adds missing-policy snapshot. |
policies/test-data/package-broker/responses/policy-management.invalid.response.json |
Adds invalid-policy snapshot. |
policies/test-data/package-broker/responses/policy-management.active.response.json |
Adds active-policy snapshot. |
policies/test-data/package-broker/requests/policy-validation.request.json |
Adds raw validation request. |
policies/test-data/package-broker/requests/policy-replacement.update.request.json |
Adds update intent fixture. |
policies/test-data/package-broker/requests/policy-replacement.replace-identity.request.json |
Adds identity-replacement fixture. |
policies/test-data/package-broker/requests/policy-replacement.repair.request.json |
Adds repair intent fixture. |
policies/test-data/package-broker/requests/policy-replacement.overwrite.request.json |
Adds confirmed-overwrite fixture. |
policies/test-data/package-broker/requests/policy-replacement.create.request.json |
Adds create intent fixture. |
policies/rust/now-policy/tests/policy_samples.rs |
Tests drafts and boolean matches. |
policies/rust/now-policy/src/schema.rs |
Adds draft-schema generation. |
policies/rust/now-policy/src/policy.rs |
Adds draft models and validation. |
policies/rust/now-policy/schema/devolutions.now-policy.schema.json |
Regenerates policy schema. |
policies/rust/now-policy/README.md |
Documents JSON-only drafts. |
policies/rust/now-policy/CHANGELOG.md |
Records model changes. |
policies/rust/now-policy/Cargo.toml |
Removes YAML dependency. |
policies/rust/now-policy/assets/samples/corporate-allowlist.policy.yaml |
Removes YAML sample. |
policies/rust/now-policy-server-template/tests/support/mock.rs |
Extends server mock. |
policies/rust/now-policy-server-template/tests/sample_documents.rs |
Tests routes and fixtures. |
policies/rust/now-policy-server-template/src/server.rs |
Adds management routes and mappings. |
policies/rust/now-policy-server-template/README.md |
Documents server endpoints. |
policies/rust/now-policy-server-template/CHANGELOG.md |
Records server contract changes. |
policies/rust/now-policy-api/src/policy.rs |
Adds draft schema reference. |
policies/rust/now-policy-api/src/management.rs |
Defines management contracts. |
policies/rust/now-policy-api/src/lib.rs |
Exports management models and markers. |
policies/rust/now-policy-api/src/enums.rs |
Adds management error codes. |
policies/rust/now-policy-api/src/api.rs |
Adds validation to errors. |
policies/rust/now-policy-api/README.md |
Documents management architecture. |
policies/rust/now-policy-api/openapi/now-policy-api.yaml |
Adds generated management OpenAPI. |
policies/rust/now-policy-api/CHANGELOG.md |
Records API additions. |
policies/dotnet/Devolutions.Now.Policy.Model/README.md |
Documents .NET draft model. |
policies/dotnet/Devolutions.Now.Policy.Model/PolicyModels.cs |
Adds draft conversion models. |
policies/dotnet/Devolutions.Now.Policy.Model/PolicyJson.cs |
Adds draft and boolean validation. |
policies/dotnet/Devolutions.Now.Policy.Model/Devolutions.Now.Policy.Model.csproj |
Removes YamlDotNet. |
policies/dotnet/Devolutions.Now.Policy.Model.Tests/PolicyTests.cs |
Tests draft conversions. |
policies/dotnet/Devolutions.Now.Policy.Client/README.md |
Documents client methods. |
policies/dotnet/Devolutions.Now.Policy.Client/BrokerClient.cs |
Implements management client APIs. |
policies/dotnet/Devolutions.Now.Policy.Client.Tests/TestData.cs |
Classifies new fixtures. |
policies/dotnet/Devolutions.Now.Policy.Client.Tests/PolicyManagementClientTests.cs |
Tests management client behavior. |
policies/dotnet/Devolutions.Now.Policy.Client.Tests/MetaModelTests.cs |
Verifies source-generated DTOs. |
policies/dotnet/Devolutions.Now.Policy.Client.Tests/DtoRoundTripTests.cs |
Adds contract round-trip tests. |
policies/dotnet/Devolutions.Now.Policy.Api/README.md |
Documents management DTOs. |
policies/dotnet/Devolutions.Now.Policy.Api/PolicyManagementModels.cs |
Defines .NET management DTOs. |
policies/dotnet/Devolutions.Now.Policy.Api/MetaModels.cs |
Extends structured errors. |
policies/dotnet/Devolutions.Now.Policy.Api/Enums.cs |
Adds strict management errors. |
policies/dotnet/Devolutions.Now.Policy.Api/BrokerJson.cs |
Adds management serialization contexts. |
policies/dotnet/Devolutions.Now.Policy.Api/BrokerApi.cs |
Adds protocol discriminators. |
Cargo.lock |
Removes Rust YAML dependency. |
Suppressed comments (1)
policies/dotnet/Devolutions.Now.Policy.Api/BrokerJson.cs:119
- This validation does not reject null entries in
PolicyValidationResult.Findings.RespectNullableAnnotationsdoes not enforce collection-element nullability, so a successful response or error containing"Findings":[null]is accepted by the .NET client while Rust rejects it, and callers can then fail when reading a finding. Explicitly reject null finding elements here.
private static void ValidateValidation(PolicyValidationResult validation)
{
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+39
to
+46
| switch (value) | ||
| { | ||
| ValidateRequiredCollectionElements(policy); | ||
| case PolicyDocument policy: | ||
| ValidateRequiredCollectionElements(policy); | ||
| break; | ||
| case PolicyDraftDocument draft: | ||
| ValidateRequiredCollectionElements(draft); | ||
| break; |
Comment on lines
+110
to
+116
| private static void ValidateManagement(PolicyManagementSnapshot management) | ||
| { | ||
| if (management.Policy is { } policy) | ||
| { | ||
| PolicyJson.ValidateRequiredCollectionElements(policy); | ||
| } | ||
| } |
Comment on lines
+116
to
+119
| if (values.Count > 1) | ||
| { | ||
| throw new JsonException($"The JSON array at {path} must contain exactly one value when present."); | ||
| } |
Comment on lines
+426
to
+430
| if values.len() > 1 { | ||
| return Err(serde::de::Error::custom( | ||
| "boolean match arrays must contain exactly one value when present", | ||
| )); | ||
| } |
Require atomic stale-token snapshots, enforce validation and management invariants, preserve legacy route 404s, and map unsafe paths to HTTP 409. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Apply semantic invariants to both C# deserialization modes, restrict opaque values to safe ASCII, and preserve nullable optional schemas without weakening required states. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add the separate 16 MiB policy-management body limit, align Unicode text bounds, and distinguish unsupported non-JSON policy paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
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
PolicyDraftDocumentmodels with explicit committed/draft conversionsBreaking changes
parse_policy_yamland .NETPolicyDocument.ParseYaml(public inDevolutions.Now.Policy.Model2026.8.13)PackageBrokerServermanagement methodsOpenAPI YAML generation and unrelated YAML request fixtures remain supported.
Contract notes
GET /v1/policyis unchangedGET /v1/policy/management,POST /v1/policy/validate, andPUT /v1/policyStringPattern,VersionString, andCustomParameterStringbounds use Unicode scalar/code-point counts across Rust, .NET, and JSON SchemaStalePolicyStoreTokenerrors carry the atomic currentManagementsnapshot for an exact-token confirmed overwrite retryUnsafePolicyPathmaps to HTTP 409; authentication/admin/elevation failures retain 401/403.yaml,.yml, extensionless, or otherwise non-JSON policy paths usePolicyReadOnlyReason.UnsupportedFormatandErrorCode.UnsupportedPolicyFormatwith HTTP 422UnsupportedEndpointis optional explicit implementation behaviorMAX_POLICY_MANAGEMENT_BODY_BYTES/BrokerApi.MaxPolicyManagementBodyBytesis 16 MiB and applies to the complete validate/replace HTTP body, including the envelope; package operations retain the separate advertised 256 KiB defaultCoordination
This is the first dependency in the coordinated Phase 2 rollout. It follows merged Phase 1 inspection contract #93. Gateway and UniGetUI PR links will be added by their coordinated follow-up work.
Validation
cargo test --workspace --lockedcargo clippy --workspace --all-targets --locked -- -D warningsdotnet format ... --verify-no-changesUnpublished exact-head artifacts
Built from
ec592a91f95a66c8a79b7d612ed73d931ef74aebas version2026.8.29-phase2.ec592a91; not published.8f7cf0e463bbeced08a79c726d70c847360c1e0c3ff4f470a6b1aa8a14f461c8df5a120ab6735f3f88ba822e9f941aa210d5d1afc5de9699639552473bd4fe7e9f0d75c5410d58e3984e9c5c1782082eaec8e8d43f7dd3f636f7729b500e03a818268e0d6dc036a3ad20a4c8329f92fb57052210435c5b5733ca797263396f8e90cde0d7953901c8012ce2aecc621ae7b8a05c12423bc26b38f172cd151bba28e98147e0b6d9c2a2cfbc83d2f2f00af2673a62c544c7240e0c8f4a90e612b017Source artifacts:
759481ac915fb0d48a602f90ad037261d5045c9a3ae906d293fef7ff3c74d469cd156264ed107890e0eeb9046d19fe0caf9bbc3f270235d434533bb325626fe8