Skip to content

Step State: propagate step result State to later steps (#346) - #350

Merged
blindzero merged 7 commits into
mainfrom
feature/346-step-state
Nov 1, 2026
Merged

blindzero merged 7 commits into
mainfrom
feature/346-step-state

Conversation

@blindzero

Copy link
Copy Markdown
Owner

Summary

Steps publish State under their step name; later steps read it as State.<StepName>.<Key> in Precondition and in With templates. Design was folded into docs/extend/steps.md (section Step State).

Catalog

  • Optional StateSchema (same key schema as WithSchema); invalid schemas fail at catalog load (InvalidStateSchema).
  • Handler State is validated against it (InvalidStepHandlerResult): undeclared keys, missing required keys, ScriptBlocks, PSCredential/SecureString. A step without StateSchema must not return State.

Planning

  • With strings with {{State...}} stay unresolved in the plan (and plan export) and are recorded in PlanStep.DeferredWith (path, segments, key schema). Their Request placeholders must resolve at planning time.
  • References are validated: StateReferenceNotAllowed (Condition, Provider/AuthSessionName/AuthSessionOptions), StateReferenceInvalid (name not an identifier), StateReferenceUnknownStep (producer does not run earlier), StateReferenceAmbiguous (name in both Steps and OnFailureSteps), StateReferenceNotDeclared.

Execution

  • Completed steps publish a data-only copy of their State; NotApplicable / PreconditionSkipped / Blocked / Failed publish nothing. OnFailureSteps see State of completed steps.
  • Preconditions get the State root (missing producer → $null, use Exists).
  • Deferred strings are resolved once, from the original workflow string, against Request and State right before the step; then validated against the stored key schema. Missing values fail the step (StateReferenceUnresolved). Request values are never re-scanned for templates (no injection).

Steps / examples / docs

  • IdLE.Step.Mailbox.GetInfo declares StateSchema = @{ Keys = @{ Mailbox = ... } }.
  • exo-leaver.psd1 uses State.GetMailboxInfo.Mailbox in a Precondition (convert only user/shared mailboxes) and in the completion message.
  • Step reference generator renders an Outputs (State.*) table.
  • Docs: steps.md, preconditions.md, templates.md, conditions.md, security.md.

Breaking changes

  • A handler returning State without StateSchema now fails (InvalidStepHandlerResult). Only Mailbox.GetInfo returned State; it declares StateSchema now.
  • Step names referenced via State must be identifiers.

Testing

  • New tests/Core/StepState.Tests.ps1 (catalog, planning validation, execution, handler result validation, failed/missing producer, ScriptBlock and credential rejection, no template injection from request data).
  • End-to-end test running examples/workflows/templates/exo-leaver.psd1 with a mock EXO provider.
  • Generator test for the State outputs table.
  • ./tools/Invoke-IdlePesterTests.ps1: 1067 passed, 0 failed.
  • ./tools/Invoke-IdleScriptAnalyzer.ps1: no findings.

Known limitation (pre-existing): Resolve-IdleWorkflowTemplates flattens nested arrays, so a State template inside a nested array in With could get a shifted index.

Closes #346

🤖 Generated with Claude Code

blindzero and others added 6 commits November 1, 2026 13:35
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Steps publish State under their step name; later steps read it as
State.<StepName>.<Key> in Preconditions and in With templates.

- Catalog: optional StateSchema (same key schema as WithSchema,
  InvalidStateSchema). Handler State is validated against it and must not
  contain ScriptBlocks, PSCredential or SecureString.
- Planning: With strings with State placeholders stay unresolved and are
  recorded in PlanStep.DeferredWith with their key schema; references are
  validated (StateReferenceNotAllowed/Invalid/UnknownStep/Ambiguous/
  NotDeclared). Condition cannot use State.
- Execution: completed steps publish a data-only copy; Preconditions get the
  State root; deferred strings are resolved once against Request and State
  before the step runs (StateReferenceUnresolved on missing values).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mple (#346)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T15:52:07.658500Z 45a0687 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Verdict: PASS

The PR adds step State propagation with schema validation, reference checks at planning time, and deferred With resolution. I found no CRITICAL issues in the parts I read.

Findings: none that I could tie to a concrete line.

Scope of this review: I read the PR metadata, the file list and Resolve-IdleDeferredStepWith.ps1 in full. I did not run the Pester tests or PSScriptAnalyzer, and I did not review the remaining changed files line by line.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

Code Coverage Report

Overall Project 77.86% 🍏

There is no coverage information present for the Files changed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45a0687e50

ℹ️ 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".

)

Also emit single backticks in the generated State outputs text; the docs
audit read the double-backtick span with <StepName> as a JSX tag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@claude

claude Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Verdict: PASS

No CRITICAL findings found. I read the PR description, the changed-file list and the deferred-With resolver (Resolve-IdleDeferredStepWith.ps1). The sandbox denied approval to run the Pester tests, so they were not run. I did not read every changed file in full, so this is a partial review.

Findings:

  • CRITICAL: none
  • MAJOR: none
  • MINOR: none

@blindzero
blindzero merged commit 4a26a0f into main Nov 1, 2026
9 checks passed
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.

Steps: propagate step result State to later steps

1 participant