Conversation
…pulation Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
…s per capability, IdLE.Identity.Read support, fixture files Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Code Coverage Report
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08ac130bea
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Adds first-class, planning-time ContextResolvers to IdLE workflows so read-only provider capabilities can populate Request.Context.* before step condition evaluation, enabling portable condition logic without host-side enrichment.
Changes:
- Extends workflow schema/normalization to support
ContextResolversand rejects unsupported resolver keys (e.g.,To). - Executes resolver capability calls during plan creation and writes results to predefined
Request.Contextpaths. - Adds Pester coverage + fixtures, updates mock provider behavior, and documents the read-only allow-list and context paths.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/IdLE.Core/Public/New-IdlePlanObject.ps1 |
Runs ContextResolvers during planning (before condition evaluation) and snapshots request after resolution. |
src/IdLE.Core/Public/Test-IdleWorkflowDefinitionObject.ps1 |
Normalizes workflow output to include ContextResolvers. |
src/IdLE.Core/Private/Test-IdleWorkflowSchema.ps1 |
Adds schema validation for root ContextResolvers and per-resolver allowed keys. |
src/IdLE.Core/Private/Invoke-IdleContextResolvers.ps1 |
Implements resolver orchestration: provider selection, capability dispatch, and writing to Request.Context. |
src/IdLE.Core/Private/Get-IdleReadOnlyCapabilities.ps1 |
Defines the read-only capability allow-list and fixed Request.Context output-path mapping. |
src/IdLE.Provider.Mock/Public/New-IdleMockIdentityProvider.ps1 |
Changes ListEntitlements to return empty for unknown identities (planning-time friendly). |
tests/Core/New-IdlePlan.ContextResolvers.Tests.ps1 |
Adds end-to-end tests for resolver ordering, schema failures, allow-list enforcement, snapshots, auto-selection, and templating. |
tests/fixtures/workflows/resolver-condition.psd1 |
Fixture: entitlement resolver enables an Exists condition. |
tests/fixtures/workflows/resolver-empty-entitlements.psd1 |
Fixture: entitlement resolver returns empty list to drive NotApplicable outcome. |
tests/fixtures/workflows/resolver-identity-read.psd1 |
Fixture: identity read resolver populates Request.Context.Identity.Profile. |
tests/fixtures/workflows/resolver-snapshot.psd1 |
Fixture: resolved context is captured in plan request snapshot. |
tests/fixtures/workflows/resolver-template.psd1 |
Fixture: templates inside With are resolved (e.g., {{Request.IdentityKeys.Id}}). |
tests/fixtures/workflows/resolver-autoselect.psd1 |
Fixture: provider auto-selection when Provider is omitted. |
tests/fixtures/workflows/resolver-no-provider.psd1 |
Fixture: failure when no provider advertises required capability. |
tests/fixtures/workflows/resolver-non-allowlisted-cap.psd1 |
Fixture: rejects non-allow-listed capability usage in a resolver. |
tests/fixtures/workflows/resolver-missing-capability.psd1 |
Fixture: rejects resolver missing required Capability. |
tests/fixtures/workflows/resolver-unknown-key.psd1 |
Fixture: rejects unknown resolver key. |
tests/fixtures/workflows/resolver-with-to-key.psd1 |
Fixture: rejects To key (output path is predefined). |
examples/workflows/mock/joiner-with-context-resolvers.psd1 |
Example workflow demonstrating resolver-driven context for conditions. |
docs/reference/capabilities.md |
Documents ContextResolvers allow-list, fixed output paths, and required With keys. |
…ct guard, missing-context guard Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Workflows requiring dynamic context (current entitlements, identity attributes) for condition evaluation had to rely on host-side enrichment. This adds a first-class
ContextResolversworkflow section that invokes read-only provider capabilities at planning time, writing results intoRequest.Context.*before step conditions are evaluated.Workflow Schema
New optional top-level
ContextResolversarray in PSD1 workflow definitions. Each capability writes to a predefined, fixed path underRequest.Context— the output path is not user-configurable, which prevents accidental overwrites and ensures consistent context shape across workflows:Auth sessions are supported in resolvers via
With.AuthSessionName/With.AuthSessionOptions, using the sameAuthSessionBrokerpattern as step execution:Predefined Context paths per capability
Request.ContextpathWithkeysIdLE.Entitlement.ListRequest.Context.Identity.EntitlementsIdentityKeyIdLE.Identity.ReadRequest.Context.Identity.ProfileIdentityKeyEngine Changes
Test-IdleWorkflowSchema— validatesContextResolversentries: requiredCapabilitykey, allowed keys (Capability,Provider,With);Tois not a valid key (output path is predefined per capability); single hashtable (instead of array) is now explicitly rejected with a clear errorTest-IdleWorkflowDefinitionObject— normalized workflow output now includesContextResolversNew-IdlePlanObject— executes resolvers immediately after workflow load, before step normalization; ensuresRequest.Contextis a writable hashtable before resolvers run (creates it when missing or$null); request snapshot captured after resolvers using a live property check so dynamically addedContextis capturedNew Private Functions
Get-IdleReadOnlyCapabilities— allow-list enforced at runtime (IdLE.Entitlement.List,IdLE.Identity.Read); non-listed capabilities are rejected with a clear errorGet-IdleCapabilityContextPath— maps each read-only capability to its fixed predefined output path underRequest.ContextInvoke-IdleContextResolvers— orchestrates resolver execution in declared order; acquires auth sessions fromProviders.AuthSessionBroker(same pattern as steps) and threads them to provider methods that declare anAuthSessionparameterGet-IdleAuthSessionBroker— extractsAuthSessionBrokerfrom theProvidersmap safelySelect-IdleResolverProviderAlias— explicit alias lookup or capability-based auto-select; iterates aliases in sorted order for determinism; throws an explicit ambiguity error when multiple providers match andProvideris not specifiedInvoke-IdleResolverCapabilityDispatch— capability→method mapping forIdLE.Entitlement.ListandIdLE.Identity.Read; usesTest-IdleProviderMethodParameterfor backwards-compatibleAuthSessionpassingSet-IdleContextValue— dotted-path writer that creates missing intermediate hashtables; throwsInvalidOperationExceptionwhen an existing intermediate node is not a dictionary (prevents silent data loss when host has pre-populated context)Provider Change
New-IdleMockIdentityProvider—ListEntitlementsnow returns@()for unknown identities instead of throwing, consistent with real API semantics and needed for planning-time calls on identities not yet createdDocumentation
docs/reference/capabilities.md— new section documents the read-only capability allow-list, predefinedRequest.Contextoutput paths, and requiredWithkeys for each capabilityTests
15 Pester tests (using fixture files under
tests/fixtures/workflows/) covering: resolver influences condition applicability,IdLE.Identity.ReadpopulatesContext.Identity.Profile,Tokey rejected as unknown, non-allow-listed capability rejection, plan snapshot capture, provider auto-selection, provider ambiguity detection, auth session threading, context type conflict detection,Request.Contextguard when property is absent, schema validation, and template resolution inWith.Original prompt
This section details on the original issue you should resolve
<issue_title>Planning-time Context Resolvers (read-only) using Provider Capabilities to populate Request.Context</issue_title>
<issue_description>## Problem Statement
IdLE evaluates step
Conditionduring planning. Many workflows require up-to-date, read-only information to decide whether a step applies, for example:Today this requires host-side enrichment, which reduces portability and standardization.
We want a first-class, portable mechanism to resolve such read-only information during planning, similar to Terraform “data sources”, while keeping IdLE guardrails:
Proposed Solution
1) Workflow-level
ContextResolverssection (planning-time)Add an optional workflow section:
ContextResolvers: list of resolversCapability: provider capability to call (read-only only), e.g.:IdLE.Entitlement.ListIdLE.Identity.Get(or similar, if/when defined)IdLE.Device.List(if/when Intune provider exists)Provider: optional selector (if multiple providers support the capability)With: resolver inputs (identity keys, filters, etc.)To: path relative toRequest.Context(e.g.,Identity.Entitlements,Identity.Attributes,Devices.Intune.ManagedDevices)Rules:
ToMUST write underRequest.Context.*only.Topoints outsideRequest.Context, planning MUST fail fast with a clear validation error.ContextResolvers.2) Planning pipeline behavior
During plan creation:
ContextResolversschema.Ensure*/ modifying capabilitiesRequest.Context.*atTo.Conditionusing the now-populatedRequest.Context.*.Request.Context.*inRequestSnapshot(per Issue 2).3) Provider extensibility model
ContextResolversreuses this system.4) Minimum viable resolver (required for v1)
Implement at least one end-to-end resolver based on an existing capability:
Capability: IdLE.Entitlement.ListRequest.Context.Identity.Entitlements(or the configuredTo)Alternatives Considered
Impact
Dependencies
Request.IntentandRequest.Context).Request.Contextsafely).Definition of Done (Step-0-Ready / Agent-Safe)
Design / Contracts
ContextResolversand validate it.ContextResolvers.IdLE.Entitlement.List.Implementation
ContextResolversbefore condition evaluation during plan build.Request.Context.*only.Tois outsideRequest.Context.Tests (Pester)
TooutsideRequest.Contextis rejected.Docs / Examples
ContextResolversand referencing `Request.Context.Identity.Entitlemen...🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.