Skip to content

Make Step WithSchema validation consistent and mandatory via Step Metadata#264

Merged
blindzero merged 6 commits into
mainfrom
copilot/make-step-schema-validation-consistent
Mar 15, 2026
Merged

Make Step WithSchema validation consistent and mandatory via Step Metadata#264
blindzero merged 6 commits into
mainfrom
copilot/make-step-schema-validation-consistent

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 15, 2026

  • Understand codebase and create plan
  • Create StepMetadataCatalog.psd1 data files for each step pack (Common, Mailbox, DirectorySync) - separate, commented, data-only PSD1 files
  • Update Get-IdleStepMetadataCatalog.ps1 in each step pack to load from .psd1 file
  • Add Test-IdleWithSchema validator to Resolve-IdleStepMetadataCatalog.ps1 (mandatory WithSchema with actionable error messages)
  • Update ConvertTo-IdleWorkflowSteps.ps1 to use WithSchema (RequiredKeys + OptionalKeys) instead of AllowedWithKeys - fail-fast with clear error messages
  • Simplify Test-IdleStepDefinition.ps1 (remove duplicate Condition DSL schema validation)
  • Update New-IdleTestStepMetadata test helper to include WithSchema (permissive by default)
  • Create fixture files withschema-disable-unknown-key.psd1, withschema-disable-missing-key.psd1, withschema-disable-case-insensitive.psd1, joiner-normalized.psd1, invoke-two-emitevent-steps.psd1
  • Update Resolve-IdleStepMetadataCatalog.Tests.ps1 to use fixture files instead of inline workflows
  • Update New-IdlePlan.Tests.ps1 to use joiner-normalized.psd1 fixture; restore EnsureAttributes with correct required keys
  • Remove all fake step type workarounds (CurrentTest, ProcessUser) - replaced with IdLE.Step.EmitEvent backed by fixture files
  • Update docs/extend/steps.md to document WithSchema as mandatory step metadata contract
  • Update docs/extend/extensibility.md to reference WithSchema and link to the metadata contract section
  • Run full test suite - 841 tests pass, 0 failures
Original 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:

  • Only some StepTypes provide AllowedWithKeys in their Step metadata.
  • When AllowedWithKeys is missing, plan creation cannot detect typos/unknown With.* keys for that StepType (e.g. With.Proivder), and those issues may surface later (or never), reducing reliability and breaking fail-fast expectations.
  • The Step metadata catalog loader validates RequiredCapabilities, but does not validate the structure and type of AllowedWithKeys.
  • Condition schema validation is performed in multiple places (workflow validation and plan normalization), increasing complexity and risk of divergence.

This undermines IdLE's consistency and fail-fast guardrails for configuration-driven workflows.

Proposed Solution

Goals

  1. Make Step schema validation consistent and fail-fast during plan creation.
  2. Ensure every StepType defines its supported With.* contract in a data-only metadata structure.
  3. Provide a forward-compatible metadata structure that can later validate:
    • required keys,
    • optional keys,
    • nested keys (sub-keys),
    • value types.

1) Make With-schema metadata mandatory (breaking)

Breaking change: Every StepType metadata entry MUST declare its With schema. 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 AllowedWithKeys with a forward-compatible WithSchema

Because required keys are also allowed keys, rename the concept to avoid redundancy and enable future sub-key/type checks.

Proposed metadata shape (data-only):

@{
  'IdLE.Step.Example' = @{
    RequiredCapabilities = @('Some.Capability')
    WithSchema = @{
      RequiredKeys = @('IdentityKey')      # keys that MUST exist
      OptionalKeys = @('Provider','AuthSession','Keep')  # keys that MAY exist

      # Optional: typed/nested schema (future-ready; implementable now in a limited form)
      Keys = @{
        Keep = @{
          Type = 'Hashtable'               # 'String' | 'Int32' | 'Boolean' | 'String[]' | 'Hashtable' | ...
          Required = $false
          Schema = @{
            Kind = @{ Type = 'String'; Required = $true }
            Id   = @{ Type = 'String'; Required = $true }
          }
        }
      }
    }
  }
}

Implementation approach (V1):

  • Mandatory: WithSchema.RequiredKeys (string[]) and WithSchema.OptionalKeys (string[]).
  • Plan-time validation must enforce:
    • no unknown keys: With.Keys ⊆ (RequiredKeys ∪ OptionalKeys)
    • all required keys exist
  • Optional (nice-to-have within this same issue if small): validate WithSchema.Keys for keys present in With:
    • type match (e.g. Hashtable, String, String[], Boolean, Int32)
    • nested schema validation for Hashtable when Schema is provided

Note: 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:

  • WithSchema must exist for every StepType.
  • RequiredKeys and OptionalKeys must be arrays of non-empty strings (case-insensitive uniqueness).
  • RequiredKeys must be a subset of (RequiredKeys ∪ OptionalKeys) by construction (no duplicates across sets).
  • If Keys exists:
    • it must be a hashtable
    • each entry must have a supported Type
    • nested Schema must be a hashtable with the same constraints

Fail-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:

  • Keep workflow validation as: shape + data-only (no scriptblocks, correct top-level keys).
  • Keep all plan-time checks in one place (plan normalization):
    • condition schema validation
    • resolvable path validation
    • condition evaluation

Concretely:

  • Reduce Test-IdleStepDefinition to only:
    • step is IDictionary/hashtable
    • required top-level keys exist (Name, Type)
    • With and Condition are hashtables if present
    • Assert-IdleNoScriptBlock (data-only)
  • Ensure ConvertTo-IdleWorkflowSteps remains the single source of truth for:
    • WithSchema validation
    • condition schema + path resolvability + evaluation

5) 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.

Copilot AI and others added 2 commits March 15, 2026 13:21
…nges + tests)

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
… review)

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copilot AI changed the title [WIP] Make Step schema validation consistent and mandatory via Step Metadata Make Step WithSchema validation consistent and mandatory via Step Metadata Mar 15, 2026
Copilot AI requested a review from blindzero March 15, 2026 13:25
Comment thread tests/Core/Resolve-IdleStepMetadataCatalog.Tests.ps1 Outdated
Comment thread tests/Core/Resolve-IdleStepMetadataCatalog.Tests.ps1 Outdated
Comment thread tests/Core/Resolve-IdleStepMetadataCatalog.Tests.ps1 Outdated
Comment thread tests/Core/New-IdlePlan.Tests.ps1 Outdated
Comment thread tests/Core/New-IdlePlan.Tests.ps1 Outdated
Comment thread tests/Core/New-IdlePlan.ContextResolvers.Tests.ps1 Outdated
Comment thread src/IdLE.Core/Private/Test-IdleStepDefinition.ps1
…EmitEvent

Co-authored-by: blindzero <13959569+blindzero@users.noreply.github.com>
Copilot AI requested a review from blindzero March 15, 2026 13:55
Copy link
Copy Markdown
Owner

@blindzero blindzero left a comment

Choose a reason for hiding this comment

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

@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>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 15, 2026

@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 c...

Done in a3010e6. All fake step type workarounds removed:

  • Invoke-IdlePlan.Tests.ps1: ProcessUser replaced by invoke-two-emitevent-steps.psd1 fixture with two IdLE.Step.EmitEvent steps (no required keys, no provider capabilities needed)
  • No more IdLE.Step.CurrentTest or IdLE.Step.ProcessUser anywhere in the codebase

Docs updated for consistency:

  • docs/extend/steps.md: added "Step metadata contract" section documenting WithSchema as mandatory (RequiredKeys + OptionalKeys), validation rules, and how step packs expose their catalog
  • docs/extend/extensibility.md: updated "Add a new step" to reference WithSchema and link to the metadata contract section

Copilot AI requested a review from blindzero March 15, 2026 14:31
@blindzero blindzero marked this pull request as ready for review March 15, 2026 14:38
Copilot AI review requested due to automatic review settings March 15, 2026 14:38
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 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 updates Get-IdleStepMetadataCatalog to load from it.
  • Adds mandatory WithSchema validation in Resolve-IdleStepMetadataCatalog and enforces WithSchema (required/optional keys + unknown-key rejection) during step normalization.
  • Updates/extends Pester coverage using workflow fixtures and refreshes extension docs to document the WithSchema contract.

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.

Comment thread src/IdLE.Steps.Common/Public/Get-IdleStepMetadataCatalog.ps1 Outdated
Comment thread src/IdLE.Steps.DirectorySync/Public/Get-IdleStepMetadataCatalog.ps1 Outdated
Comment thread src/IdLE.Steps.Mailbox/Public/Get-IdleStepMetadataCatalog.ps1 Outdated
Comment thread src/IdLE.Core/Private/ConvertTo-IdleWorkflowSteps.ps1 Outdated
Comment thread src/IdLE.Core/Private/Resolve-IdleStepMetadataCatalog.ps1 Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

Code Coverage Report

Overall Project 74.74% 🍏

There is no coverage information present for the Files changed

@blindzero blindzero merged commit 52672dc into main Mar 15, 2026
8 checks passed
@blindzero blindzero deleted the copilot/make-step-schema-validation-consistent branch March 22, 2026 16:23
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.

Make Step With-schema validation consistent and mandatory via Step Metadata

3 participants