Skip to content

feat(policy): support native PolicyPlugin exports from module files#115

Open
yxbh wants to merge 1 commit intomicrosoft:mainfrom
yxbh:feat/native-plugin-loader-v2
Open

feat(policy): support native PolicyPlugin exports from module files#115
yxbh wants to merge 1 commit intomicrosoft:mainfrom
yxbh:feat/native-plugin-loader-v2

Conversation

@yxbh
Copy link
Copy Markdown

@yxbh yxbh commented Apr 8, 2026

Summary

Allow policy modules to export a native \PolicyPlugin\ object (with detectors, hooks, and recommenders) instead of being limited to the \PolicyConfig\ criteria DSL.

What changed

File Change
\packages/core/src/services/policy/types.ts\ Added \isNativePlugin()\ type guard, \�alidateNativePlugin()\ with thorough hook/array/type checking
\packages/core/src/services/policy/index.ts\ Re-exported new functions
\packages/core/src/services/policy.ts\ \loadPolicy()\ returns \PolicyConfig | PolicyPlugin\ union, \pathToFileURL\ fix for Windows
\packages/core/src/services/policy/loader.ts\ \loadPluginChain()\ detects and adds native plugins directly
\packages/core/src/services/readiness/index.ts\ Auto-enables engine path when native plugins present (without mutating caller options)
\src/services/tests/policy-engine-types.test.ts\ 24 new tests for type guard and validation
\src/services/tests/policy-loader.test.ts\ 6 new tests for native plugin loading
\src/services/tests/policy.test.ts\ Fixed type narrowing with \loadPolicyConfig()\ helper

Why

The \PolicyConfig\ DSL (\criteria.add/disable/override) is great for simple checks but can't express:

  • Signal mutation via \�fterDetect\ hooks (\SignalPatch)
  • Cross-signal recommendations (e.g. per-MCP-server denied signals)
  • Rich metadata on recommendations (reference URLs, impact levels)

Native \PolicyPlugin\ exports unlock the full 5-stage engine pipeline for external policy authors.

Native plugin detection

\isNativePlugin()\ detects exports with:

  1. A \meta\ object with a non-empty \meta.name\ string
  2. No root-level
    ame\ string (which would indicate a \PolicyConfig)
  3. Valid \meta.sourceType/\meta.trust\ values if present

\�alidateNativePlugin()\ then verifies:

  • Hook properties are functions
  • \detectors/
    ecommenders\ are arrays of objects with valid \id\ and callable members
  • At least one hook is implemented

Windows fix

\import(resolvedPath)\ fails on Windows for paths like \C:\...\ because Node treats \C:\ as a URL scheme. Fixed by using \pathToFileURL(resolved).href.

Testing

  • 671 tests passing (34 new)
  • Validated end-to-end with a full Microsoft corporate policy plugin (9 signals, 9 recommendations, signal mutation, cross-signal logic)

@yxbh yxbh requested a review from pierceboggan as a code owner April 8, 2026 01:43
Copilot AI review requested due to automatic review settings April 8, 2026 01:43
@yxbh yxbh requested a review from digitarald as a code owner April 8, 2026 01:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends the policy loading pipeline to support native PolicyPlugin exports from module files (detectors/hooks/recommenders), in addition to the existing declarative PolicyConfig DSL, and fixes Windows dynamic import() path handling.

Changes:

  • Add native plugin detection/validation helpers (isNativePlugin, validateNativePlugin) and re-export them.
  • Update policy loading and plugin-chain construction to accept/route native PolicyPlugin exports.
  • Update readiness reporting and tests to accommodate loadPolicy() returning a PolicyConfig | PolicyPlugin union and to exercise native plugin loading/execution.

Reviewed changes

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

Show a summary per file
File Description
packages/core/src/services/policy/types.ts Adds native plugin type guard + validation helpers.
packages/core/src/services/policy/index.ts Re-exports new helpers from the policy public surface.
packages/core/src/services/policy.ts Updates loadPolicy() to return a union and uses pathToFileURL() for Windows-safe dynamic imports.
packages/core/src/services/policy/loader.ts Adds native plugin detection path and inserts native plugins directly into the chain with normalized trust/sourceType.
packages/core/src/services/readiness/index.ts Skips native plugins in legacy resolveChain path and auto-enables engine/shadow execution when native plugins are present.
src/services/__tests__/policy-engine-types.test.ts Adds unit tests for isNativePlugin and validateNativePlugin.
src/services/__tests__/policy-loader.test.ts Adds tests for loading/executing native plugins via loadPluginChain.
src/services/__tests__/policy.test.ts Adds helper to narrow loadPolicy() results to PolicyConfig for existing tests.

Comment thread packages/core/src/services/policy/types.ts
Comment thread packages/core/src/services/policy.ts
Comment thread src/services/__tests__/policy-loader.test.ts
Allow policy modules to export a native PolicyPlugin object (with detectors,
hooks, and recommenders) instead of being limited to the PolicyConfig DSL.

Changes:
- isNativePlugin() type guard with validation of meta fields
- validateNativePlugin() with thorough hook/array/type checking
- loadPolicy() returns PolicyConfig | PolicyPlugin union
- loadPluginChain() detects and adds native plugins directly
- readiness auto-enables engine path when native plugins are present
- pathToFileURL fix for Windows dynamic import

Tests: 671 passing (34 new tests for type guard, validation, and loader)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@yxbh yxbh force-pushed the feat/native-plugin-loader-v2 branch from 49cf0b4 to 0cb4bd1 Compare April 8, 2026 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants