Skip to content

Add package policy editor - #5335

Merged
Marc-André Moreau (mamoreau-devolutions) merged 68 commits into
mainfrom
cbenoit-phase-2-policy-editor
Sep 21, 2026
Merged

Marc-André Moreau (mamoreau-devolutions) merged 68 commits into
mainfrom
cbenoit-phase-2-policy-editor

Conversation

@CBenoit

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

Copy link
Copy Markdown
Member
  • Add a Windows-only Devolutions Agent policy management dashboard and full structured/raw policy editor.
  • Use the authoritative GET /v1/policy/management snapshot for the page, with correct transport-unavailable versus malformed-response classification.
  • Add local and Agent validation, fixed findings navigation, warning acknowledgement, exact-token conflict handling, dirty-state protection, accessible/localized help, responsive date/time validity controls, and high-signal risk advisories.
  • Add a separately built NativeAOT elevated helper with mutually authenticated, bounded, single-use IPC. Only the helper performs ReplacePolicy; its Agent connection verifies the kernel-reported server process, protected executable path, signer, and identification-only impersonation before transmitting policy data.
  • Fold the complete former Add read-only package broker policy inspector #5292 inspector/helper implementation into this standalone PR targeting main.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Moderate correctness, performance, contract-boundary, and post-commit protocol issues remain unresolved.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a Windows-only Agent policy editor with structured/raw editing, validation, stale-token handling, and secure elevated writes.

Changes:

  • Adds policy-management UI, lifecycle guards, localization, and search integration.
  • Introduces authenticated NativeAOT elevation and bounded IPC.
  • Expands packaging, build automation, and test coverage.
File summaries
File Description
UniGetUI.iss Handles helper installation cleanup.
src/UniGetUI.Windows.slnx Adds the elevated-helper project.
src/UniGetUI.Tests/SettingsSearchIndexTests.cs Tests policy search indexing.
src/UniGetUI.Tests/PolicyEditor/PolicyRuleOperationsTests.cs Tests rule mutations.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorViewModelFakes.cs Provides editor test doubles.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorTestFixtures.cs Provides policy test fixtures.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorTemplatesTests.cs Tests draft templates.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorSessionCloseGuardTests.cs Tests dirty-session protection.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorRetryResolverTests.cs Tests conflict retry decisions.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorLocalizationTests.cs Tests localization-key coverage.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorFindingIndexTests.cs Tests bounded finding indexing.
src/UniGetUI.Tests/PolicyEditor/PolicyEditorDraftFingerprintTests.cs Tests canonical fingerprints.
src/UniGetUI.Tests/AgentPolicyInspectorViewModelTests.cs Tests policy-management states.
src/UniGetUI.PackageEngine.Tests/PolicyWriteElevation/PolicyElevationProtocolTests.cs Tests elevation protocol constants.
src/UniGetUI.PackageEngine.Tests/PolicyWriteElevation/PolicyElevationPathsTests.cs Tests authenticated paths.
src/UniGetUI.PackageEngine.Tests/PolicyWriteElevation/PolicyElevationLaunchArgumentsTests.cs Tests launch-argument validation.
src/UniGetUI.PackageEngine.Tests/PolicyWriteElevation/PolicyElevationHelperLocatorTests.cs Tests helper discovery.
src/UniGetUI.PackageEngine.Tests/PolicyWriteElevation/PolicyElevationFrameTests.cs Tests bounded framing.
src/UniGetUI.PackageEngine.Tests/PackageOperationsTests.cs Updates broker-operation regressions.
src/UniGetUI.PackageEngine.Tests/BrokerPolicyInspectorTests.cs Tests policy validation.
src/UniGetUI.PackageEngine.AgentBroker/UniGetUI.PackageEngine.AgentBroker.csproj Updates policy dependencies.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Protocol/PolicyElevationPaths.cs Defines protocol paths.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Protocol/PolicyElevationMessages.cs Defines IPC messages.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Protocol/PolicyElevationJsonContext.cs Supplies generated JSON metadata.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Protocol/PolicyElevationEnumConverters.cs Serializes protocol enums.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Protocol/PolicyElevationArguments.cs Parses helper arguments.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/PolicyElevationPipeServer.cs Creates secured IPC pipes.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/PolicyElevationOutcome.cs Models elevation outcomes.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/PolicyElevationHelperLocator.cs Locates the packaged helper.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Interop/WindowsProcessInspector.cs Inspects process identity.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Interop/WindowsPeerAuthenticator.cs Authenticates IPC peers.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Interop/WindowsAuthenticodeTrustVerifier.cs Verifies executable signatures.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Interop/PolicyElevationTrustPolicy.cs Defines signer trust decisions.
src/UniGetUI.PackageEngine.AgentBroker/PolicyWriteElevation/Interop/PolicyElevationAccessPolicy.cs Defines elevation access checks.
src/UniGetUI.PackageEngine.AgentBroker/PolicyManagement/BrokerPolicyManagementModels.cs Defines management outcomes and limits.
src/UniGetUI.PackageEngine.AgentBroker/BrokerPolicyInspector.cs Strengthens policy validation.
src/UniGetUI.Avalonia/Views/SoftwarePages/Interfaces/PageInterfaces.cs Defines asynchronous leave guards.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/SettingsBasePage.axaml.cs Guards settings navigation.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/PolicyEditor/PolicyEditorDialog.axaml.cs Handles editor dialog interactions.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/PolicyEditor/PolicyEditorConfirmationPrompt.cs Presents save confirmations.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/AgentPolicyInspector.axaml.cs Opens editor dialogs.
src/UniGetUI.Avalonia/Views/Pages/SettingsPages/AgentPolicyInspector.axaml Adds policy-management controls.
src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs Guards window closure.
src/UniGetUI.Avalonia/Views/Controls/PolicyJsonEditor.cs Provides the raw JSON editor.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyRuleOperations.cs Implements rule-list mutations.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorTemplates.cs Creates operation-specific drafts.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorSessionCloseGuard.cs Protects unsaved changes.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorRetry.cs Resolves stale-token retries.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorRawSyntax.cs Implements strict raw parsing.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorProductionAdapters.cs Connects UI services to Agent APIs.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorPolicyContract.cs Centralizes policy contract values.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorEnums.cs Defines editor states and operations.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorDependencies.cs Defines editor service seams.
src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyDraftFingerprint.cs Computes canonical draft fingerprints.
src/UniGetUI.Avalonia/UniGetUI.Avalonia.csproj Publishes and stages the helper.
src/UniGetUI.Avalonia/Infrastructure/SettingsSearchIndex.cs Adds policy-management search actions.
src/UniGetUI.AgentPolicy.ElevatedHelper/UniGetUI.AgentPolicy.ElevatedHelper.csproj Configures NativeAOT publication.
src/UniGetUI.AgentPolicy.ElevatedHelper/PolicyReplacementExecutor.cs Executes elevated replacements.
src/UniGetUI.AgentPolicy.ElevatedHelper/app.manifest Requires administrator elevation.
scripts/build.ps1 Builds and stages the helper.
.github/workflows/build-release.yml Signs, verifies, and packages the helper.
Review details

Suppressed comments (8)

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorDialogViewModel.cs:182

  • This displays parser-generated English text verbatim. PolicyEditorRawSyntax supplies hard-coded/interpolated messages and raw JsonException.Message values, so non-English users see untranslated error details despite neighboring status text being localized. Represent syntax failures with localizable kinds/arguments and translate a bounded message here.
                syntaxError.Message,

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorDialogViewModel.cs:181

  • SyntaxError also represents valid JSON that violates the draft contract (wrong schema, policy type, or fixed precedence), so this title incorrectly tells users those documents are not JSON. Use a title such as “The document is not a valid policy draft,” or distinguish JSON parse errors from contract errors.
                CoreTools.Translate("The document is not valid JSON"),

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorRawSyntax.cs:113

  • The raw document uses the PascalCase Enforcement property, so this case-sensitive JSON Pointer cannot identify the missing block in the editor. Use /Enforcement.
            error = new PolicyEditorSyntaxError("Missing enforcement block.", "/enforcement");

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorRawSyntax.cs:121

  • Canonical raw JSON names this path Enforcement/RulePrecedence. JSON Pointer matching is case-sensitive, so the lowercase pointer cannot locate or highlight the rejected field.
                "/enforcement/rulePrecedence");

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorRawSyntax.cs:127

  • The expected raw property is Metadata; JSON Pointer member names are case-sensitive. Use /Metadata so this error points to the property the editor accepts/emits.
            error = new PolicyEditorSyntaxError("Missing metadata block.", "/metadata");

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorRawSyntax.cs:9

  • Message is populated with hard-coded English strings and raw runtime exception messages, then bound directly to the dialog. Non-English users therefore receive untranslated, runtime-dependent syntax details, and translation-source tooling cannot discover them. Carry a stable syntax-error kind plus bounded arguments/pointer and localize it at the presentation layer with literal translation keys instead of exposing Exception.Message.
public sealed record PolicyEditorSyntaxError(string Message, string Pointer);

src/UniGetUI.Avalonia/Views/Pages/SettingsPages/PolicyEditor/PolicyEditorConfirmationPrompt.cs:113

  • This count is computed from the bounded display list, whose final item is a synthetic warning whenever findings are omitted. It can therefore overcount (omitted errors) or severely undercount (omitted warnings) the warnings being acknowledged. Carry the authoritative warning count separately from the bounded findings and display that value.
    src/UniGetUI.Tests/PolicyEditor/PolicyEditorLocalizationTests.cs:108
  • This regex only discovers literal CoreTools.Translate("...") calls, but the changed editor also translates dynamic enum/severity/argument labels (for example CoreTools.Translate(Severity.ToString()) and CoreTools.Translate(label)). Removing one of those keys from lang_en.json would still leave this test green, so the claimed policy-editor localization coverage is incomplete. Enumerate those bounded dynamic key sets explicitly or refactor them to stable literal translation keys that this check can validate.
  • Files reviewed: 91/91 changed files
  • Comments generated: 4
  • Review effort level: Balanced

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

A critical policy-rule behavior and multiple unresolved correctness, accessibility, lifecycle, and dependency issues block approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 84/88 changed files
  • Comments generated: 9
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Moderate issues remain in conflict messaging, UI-thread dirty-state computation, and structured description round-tripping.

Review details

Suppressed comments (6)

Previously missed (3) — in code that hasn't changed since the last review.

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorDialogViewModel.cs:212

  • A stale-token response sets both LastWriteFailureKind and Session.HasConflict, so this earlier branch always wins and the conflict-specific “Review … then choose Overwrite” status below is unreachable. Users see only a generic broker rejection even though the UI is waiting for an exact-token overwrite decision. Prioritize HasConflict before the generic write-failure branch.
    src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorSession.cs:68
  • IsDirty synchronously serializes and compares the entire structured draft on every getter call. Every structured field edit raises IsDirty, so typing can repeatedly serialize a policy up to the 16 MiB request limit on the UI thread; cache/debounce the structured fingerprint or track dirty generations and perform the full comparison off the input path.
    src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorStructuredUi.cs:175
  • This silently converts schema-valid empty or whitespace-only descriptions to null. That changes user-authored policy data when editing in structured mode, so switching modes or saving no longer round-trips the draft exactly; preserve the value and let authoritative validation handle its length constraints.

This issue also appears in the following locations of the same file:

  • line 425
  • line 477
  • line 483

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorStructuredUi.cs:425

  • This silently converts schema-valid empty or whitespace-only rule reasons to null. Structured editing therefore mutates valid policy content instead of preserving the exact reason; assign the nullable value directly and leave validation to the Agent.
    src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorStructuredUi.cs:477
  • Whitespace is nonempty policy text, but this setter silently converts it to an omitted lower bound instead of submitting the exact value for authoritative validation. Only an empty textbox should clear MinVersion.
    src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorStructuredUi.cs:483
  • Like MinVersion, a whitespace-only upper bound is silently rewritten to null. Preserve nonempty input so structured editing does not change the draft before the Agent validates it.
  • Files reviewed: 83/89 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@CBenoit

Copy link
Copy Markdown
Member Author

Resolved every concern from review #5335 (review) at exact head 02a3e6f4ae5af52196416296e3cfbbfad05085f0:

  1. Conflict status precedence: Session.HasConflict now wins before generic write failures, so exact-token overwrite guidance is reachable. Tests cover both flags set and generic rejection without conflict.
  2. Constant-time structured dirty state: synchronous setters and IsDirty only update/read cached state. Debounced analysis captures a deep snapshot on the UI context, serializes it off-thread, and stale-suppresses by mutation generation plus baseline version. Tests cover dirty, exact revert, rapid stale analyses, live-draft isolation, large drafts, boundary reconciliation, and edit-during-save ownership.
  3. Description presence/text: HasDescription explicitly distinguishes omission from present empty text; null survives initial binding and empty, whitespace, normal text, explicit omission, and raw/structured round-trips are exact.
  4. Rule Reason presence/text: HasReason supplies the same omission versus present-empty semantics, with exact null/empty/whitespace/normal-text and mode-round-trip coverage.
  5. MinVersion: exactly empty clears the optional bound; whitespace and nonempty authored text are preserved for authoritative Agent validation, with exact round-trip tests.
  6. MaxVersion: exactly empty clears the optional bound; whitespace and nonempty authored text are preserved for authoritative Agent validation, with exact round-trip tests.

Additional race hardening rechecks raw-mode edits after an in-flight authenticated save against the new authoritative baseline and clears stale SavedWithNewerChanges when structured or raw exact reconciliation proves the draft clean. Focused policy-editor tests pass 236/236; the full Windows solution tests, Windows x64 and forced-portable builds, fresh app/helper NativeAOT publish, and 79-file integrity verification pass. Official NuGet.org-only policy packages remain 2026.9.3 from release commit 790d7c63.

@CBenoit

Copy link
Copy Markdown
Member Author

Copilot review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Three moderate issues remain in publisher handling, finding severity mapping, and restart cancellation behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (3)

Previously missed (2) — in code that hasn't changed since the last review.

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorTemplates.cs:26

  • Publisher is a schema-valid required string even when it contains only whitespace (the existing preservation regression covers this at AgentPolicyInspectorViewModelTests.cs:39-64). ReplaceIdentity() passes the active policy's publisher into this method, so such a valid policy throws here and the editor never opens. Reject only null/empty publishers, and update the whitespace test expectation accordingly.
    src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyValidationFinding.cs:30
  • Info findings fall through to Warning here. Warning findings require acknowledgement before saving (PolicyEditorSession.cs:689-696), so an informational Agent result is incorrectly shown as a warning and adds a confirmation step. Preserve all three severities explicitly.

This issue also appears on line 39 of the same file.

src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyValidationFinding.cs:41

  • The sanitized-finding path also maps Info to Warning. These findings feed the same warning acknowledgement logic, so informational results from the bounded broker adapter unnecessarily block saving behind a warning confirmation. Preserve the informational severity.
  • Files reviewed: 82/89 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/UniGetUI.Avalonia/Views/MainWindow.axaml.cs Outdated
@CBenoit

Copy link
Copy Markdown
Member Author

Review 5113628557 disposition at exact head cf4e13f933bd80ae1e391df8496d86cb714ef11d:

  1. Whitespace publisher — fixed: fail-closed templates now reject only null/empty publisher values and preserve schema-valid whitespace. A management-to-ReplaceIdentity regression proves a whitespace-only active publisher opens the editor and reaches the seeded draft unchanged.
  2. Finding Info — non-actionable stale contract assumption, hardened where representable: the mandated official Devolutions.Now.Policy.Api 2026.9.3 assembly (release commit 790d7c63, attested hash in the PR body) defines PolicyFindingSeverity as exactly Error=0 and Warning=1; there is no Info member in either direct or sanitized Agent findings. No package change or invented enum value is appropriate. The former fallthrough is nevertheless replaced by an explicit Error/Warning switch, undefined/future numeric values throw fail-closed, both official values are tested through direct and sanitized paths, and local PolicyValidationSeverity.Info is tested not to require warning acknowledgement.
  3. Restart cancellation — fixed: restart uses the same serialized awaitable dirty-editor shutdown authorization as ordinary quit. Relaunch scheduling occurs only after approval and before shutdown; decline creates no waiter, later ordinary exit still creates none, and clean/approved/concurrent/repeated cases are covered. Inline thread resolved with the concrete fix.

Validation: 260 focused tests; full Windows solution including 306 Avalonia and 493/727 PackageEngine tests; Windows x64 and forced-portable builds; fresh metadata-free app/helper NativeAOT; 79-file integrity verification; 59 translation catalogs. The PR remains draft.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Privileged-write complexity remains high, with unresolved moderate enum-mapping and metadata-preservation issues.

Review details

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

src/UniGetUI.AgentPolicy.ElevatedHelper/PolicyReplacementExecutor.cs:32

  • These casts couple the privileged operation to enum ordinals even though the elevation protocol defines independent wire enums and the contract test establishes name-based equivalence. A future shared-contract reorder or insertion would pass that test but execute a different replacement operation; map each value explicitly so unsupported values fail closed.
    src/UniGetUI.Avalonia/ViewModels/Pages/SettingsPages/PolicyEditor/PolicyEditorStructuredUi.cs:203
  • This setter silently converts a schema-valid whitespace-only support URL to null, so editing and saving an existing policy can lose user-authored metadata. Other free-form metadata and list fields preserve whitespace exactly; only an empty string should represent an omitted optional URL.
  • Files reviewed: 84/92 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@CBenoit

Copy link
Copy Markdown
Member Author

Resolved both suppressed concerns from review #5335 (review) at exact head a15e9c703a3abaf6a181543156e39905bc1453dd:

  1. Privileged enum mapping: the helper no longer casts independent wire enums by ordinal. PolicyElevationReplacementDispatcher exhaustively maps every operation and conflict-handling value before invoking the broker delegate; unsupported numeric values throw InvalidDataException. Tests cover all six mappings and prove invalid operation/conflict values make zero broker calls.
  2. SupportUrl preservation: exactly empty input maps to omission, while whitespace and nonempty values remain verbatim for authoritative Agent validation. Tests cover untouched null/initial empty binding, explicit empty clear, whitespace and valid URL round-trip, and whitespace reaching Agent validation unchanged and being rejected.

The CI whitespace annotations were also corrected with the repository formatter. Full exact-head tests/builds, official NuGet.org-only package hashes, fresh app/helper NativeAOT metadata checks, 79-file integrity validation, and 59 translation catalogs pass. The PR remains draft.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Two moderate issues remain in replacement-request size preflight and multiline localization-key scanning.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/UniGetUI.Tests/PolicyEditor/PolicyEditorLocalizationTests.cs:125

  • This regex requires the string literal to start immediately after Translate(, so existing multiline calls such as CoreTools.Translate(\n "…") are omitted from the source scan. The localization test can therefore pass even when a multiline translation key is missing from the catalogs; allow whitespace before the opening quote.
  • Files reviewed: 86/94 changed files
  • Comments generated: 1
  • Review effort level: Balanced

@CBenoit

Copy link
Copy Markdown
Member Author

Also fixed the suppressed localization-test finding from review 5114529346 in 9862195: the literal CoreTools.Translate scanner now permits whitespace/newlines before the opening quote, with a multiline extraction regression. The exact CI import-order failures in PolicyEditorDialogViewModel.cs, PolicyEditorMapper.cs, PolicyValidationFinding.cs, and AgentPolicyInspector.axaml.cs were formatted in the same commit.

@CBenoit

Copy link
Copy Markdown
Member Author

Copilot review

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>
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
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Local validation blocks valid catch-all policies, and both shipping projects use dependency versions not covered by the PR’s provenance evidence.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

src/UniGetUI.PackageEngine.AgentBroker/UniGetUI.PackageEngine.AgentBroker.csproj:13

  • These shipping dependencies are pinned to 2026.9.17, but the PR description and validation evidence attest only 2026.9.15 and provide hashes for that version. Dependency provenance is therefore not reproducible from the stated evidence. Either restore the attested version or update the provenance hashes and rerun/update the validation claims for 2026.9.17.
  • Files reviewed: 90/128 changed files
  • Comments generated: 2
  • Review effort level: Balanced

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The privileged NativeAOT helper, authenticated IPC, Windows trust verification, and broad editor lifecycle changes warrant final human security review despite strong test coverage.

Review details
  • Files reviewed: 89/129 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

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>
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
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@CBenoit Benoît Cortier (CBenoit) changed the title Add Phase 2 package policy editor Add package policy editor Sep 20, 2026
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) merged commit 1f832f0 into main Sep 21, 2026
6 of 7 checks passed
@mamoreau-devolutions
Marc-André Moreau (mamoreau-devolutions) deleted the cbenoit-phase-2-policy-editor branch September 21, 2026 02:26
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.

4 participants