Make Step WithSchema validation consistent and mandatory via Step Metadata#264
Conversation
…nges + tests) Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
… review) Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
…EmitEvent Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
blindzero
left a comment
There was a problem hiding this comment.
@copilot make sure that all "wrong workarounds" of CurrentTest or ProcessUser are removed and made consistent to the fix from last commit.
Also check and make sure to check all docs and examples for consistency regarding the changes. However, only document new behavior, no deprecated notes required.
Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Done in a3010e6. All fake step type workarounds removed:
Docs updated for consistency:
|
There was a problem hiding this comment.
Pull request overview
This PR makes WithSchema a mandatory, consistent step-metadata contract across step packs and host-supplied step types, so plan creation can fail fast on missing/unknown With.* keys.
Changes:
- Introduces
StepMetadataCatalog.psd1(data-only) per step pack and updatesGet-IdleStepMetadataCatalogto load from it. - Adds mandatory
WithSchemavalidation inResolve-IdleStepMetadataCatalogand enforcesWithSchema(required/optional keys + unknown-key rejection) during step normalization. - Updates/extends Pester coverage using workflow fixtures and refreshes extension docs to document the
WithSchemacontract.
Reviewed changes
Copilot reviewed 24 out of 24 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/fixtures/workflows/withschema-disable-unknown-key.psd1 | New fixture for unknown With.* key failure. |
| tests/fixtures/workflows/withschema-disable-missing-key.psd1 | New fixture for missing required With.* key failure. |
| tests/fixtures/workflows/withschema-disable-case-insensitive.psd1 | New fixture verifying case-insensitive With key validation. |
| tests/fixtures/workflows/joiner-onfailure.psd1 | Adds required With.IdentityKey to keep fixture valid under mandatory schemas. |
| tests/fixtures/workflows/joiner-normalized.psd1 | New “normalized plan” workflow fixture aligned with required WithSchema keys. |
| tests/fixtures/workflows/joiner-missing-caps.psd1 | Adds required With.IdentityKey to Disable step. |
| tests/fixtures/workflows/joiner-builtin.psd1 | Adds required With.IdentityKey to Disable step. |
| tests/fixtures/workflows/invoke-two-emitevent-steps.psd1 | New fixture for deterministic execution result test without custom step types. |
| tests/_testHelpers.ps1 | Tightens module-manifest discovery (filename must match module directory). |
| tests/Steps/_testHelpers.Steps.ps1 | Extends New-IdleTestStepMetadata to emit default permissive WithSchema (or caller-specified schemas). |
| tests/Core/Resolve-IdleStepMetadataCatalog.Tests.ps1 | Adds coverage for missing/invalid WithSchema and plan-time enforcement using fixtures. |
| tests/Core/New-IdlePlan.Tests.ps1 | Switches normalized-plan test to fixture and updates one test description to reference WithSchema. |
| tests/Core/Invoke-IdlePlan.Tests.ps1 | Uses fixture-based workflow (EmitEvent steps) for deterministic events test. |
| src/IdLE.Steps.Mailbox/StepMetadataCatalog.psd1 | New data-only metadata catalog with WithSchema for mailbox steps. |
| src/IdLE.Steps.Mailbox/Public/Get-IdleStepMetadataCatalog.ps1 | Loads step metadata from StepMetadataCatalog.psd1. |
| src/IdLE.Steps.DirectorySync/StepMetadataCatalog.psd1 | New data-only metadata catalog with WithSchema for directory sync steps. |
| src/IdLE.Steps.DirectorySync/Public/Get-IdleStepMetadataCatalog.ps1 | Loads step metadata from StepMetadataCatalog.psd1. |
| src/IdLE.Steps.Common/StepMetadataCatalog.psd1 | New data-only metadata catalog with WithSchema for common steps. |
| src/IdLE.Steps.Common/Public/Get-IdleStepMetadataCatalog.ps1 | Loads step metadata from StepMetadataCatalog.psd1. |
| src/IdLE.Core/Private/Test-IdleStepDefinition.ps1 | Removes duplicate Condition DSL schema validation from step-definition validation. |
| src/IdLE.Core/Private/Resolve-IdleStepMetadataCatalog.ps1 | Adds mandatory WithSchema validation (structure + duplicate detection across required/optional). |
| src/IdLE.Core/Private/ConvertTo-IdleWorkflowSteps.ps1 | Replaces AllowedWithKeys with WithSchema validation (required keys + unknown key rejection + wildcard support). |
| docs/extend/steps.md | Documents WithSchema as mandatory step metadata contract. |
| docs/extend/extensibility.md | Updates extensibility guidance to reference WithSchema and links to the contract section. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Code Coverage Report
|
StepMetadataCatalog.psd1data files for each step pack (Common, Mailbox, DirectorySync) - separate, commented, data-only PSD1 filesGet-IdleStepMetadataCatalog.ps1in each step pack to load from .psd1 fileTest-IdleWithSchemavalidator toResolve-IdleStepMetadataCatalog.ps1(mandatory WithSchema with actionable error messages)ConvertTo-IdleWorkflowSteps.ps1to useWithSchema(RequiredKeys + OptionalKeys) instead ofAllowedWithKeys- fail-fast with clear error messagesTest-IdleStepDefinition.ps1(remove duplicate Condition DSL schema validation)New-IdleTestStepMetadatatest helper to includeWithSchema(permissive by default)withschema-disable-unknown-key.psd1,withschema-disable-missing-key.psd1,withschema-disable-case-insensitive.psd1,joiner-normalized.psd1,invoke-two-emitevent-steps.psd1Resolve-IdleStepMetadataCatalog.Tests.ps1to use fixture files instead of inline workflowsNew-IdlePlan.Tests.ps1to usejoiner-normalized.psd1fixture; restoreEnsureAttributeswith correct required keysCurrentTest,ProcessUser) - replaced withIdLE.Step.EmitEventbacked by fixture filesdocs/extend/steps.mdto documentWithSchemaas mandatory step metadata contractdocs/extend/extensibility.mdto referenceWithSchemaand link to the metadata contract sectionOriginal prompt
This section details on the original issue you should resolve
<issue_title>Make Step With-schema validation consistent and mandatory via Step Metadata</issue_title>
<issue_description>## Problem Statement
Step schema validation is currently inconsistent across StepTypes:
AllowedWithKeysin their Step metadata.AllowedWithKeysis missing, plan creation cannot detect typos/unknownWith.*keys for that StepType (e.g.With.Proivder), and those issues may surface later (or never), reducing reliability and breaking fail-fast expectations.RequiredCapabilities, but does not validate the structure and type ofAllowedWithKeys.This undermines IdLE's consistency and fail-fast guardrails for configuration-driven workflows.
Proposed Solution
Goals
With.*contract in a data-only metadata structure.1) Make With-schema metadata mandatory (breaking)
Breaking change: Every StepType metadata entry MUST declare its
Withschema. If it does not, plan creation fails with a clear exception.This ensures the plan builder can always validate
With.*keys at plan-time.As there are only the steps we deliver in the project at the moment, we do not do any legacy reference remarks, comments or warnings. We just continue and provide what the change needs.
2) Replace
AllowedWithKeyswith a forward-compatibleWithSchemaBecause required keys are also allowed keys, rename the concept to avoid redundancy and enable future sub-key/type checks.
Proposed metadata shape (data-only):
Implementation approach (V1):
WithSchema.RequiredKeys(string[]) andWithSchema.OptionalKeys(string[]).With.Keys⊆ (RequiredKeys ∪ OptionalKeys)WithSchema.Keysfor keys present inWith:Hashtable,String,String[],Boolean,Int32)HashtablewhenSchemais providedNote: This remains data-only and does not introduce ScriptBlocks.
3) Validate Step metadata in the catalog loader
Extend
Resolve-IdleStepMetadataCatalog/ related helper(s) so metadata is validated consistently:WithSchemamust exist for every StepType.RequiredKeysandOptionalKeysmust be arrays of non-empty strings (case-insensitive uniqueness).RequiredKeysmust be a subset of (RequiredKeys ∪ OptionalKeys) by construction (no duplicates across sets).Keysexists:TypeSchemamust be a hashtable with the same constraintsFail-fast with actionable error messages (StepType name + offending key).
4) Remove redundant Condition schema validation (simplify)
Current state performs condition schema checks in multiple places (workflow validation + plan normalization).
Target state:
Concretely:
Test-IdleStepDefinitionto only:Name,Type)WithandConditionare hashtables if presentAssert-IdleNoScriptBlock(data-only)ConvertTo-IdleWorkflowStepsremains the single source of truth for:WithSchemavalidation5) Execution-time considerations
Plan-time validation should be the primary mechanism. Execution should still be defensive,...
📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.