Skip to content

.NET: fix(dotnet): validate declarative control-flow inputs - #9357

Merged
Vincent Biret (baywet) merged 8 commits into
mainfrom
fix/declarative-control-flow-validation
Oct 15, 2026
Merged

Vincent Biret (baywet) merged 8 commits into
mainfrom
fix/declarative-control-flow-validation

Conversation

@baywet

@baywet Vincent Biret (baywet) commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Motivation & Context

Fix inconsistent input validation in declarative workflow control-flow actions. Decision settings should follow the same value-validation contract as other action inputs, while preserving ordinary expressions and existing defaults.

Description & Review Guide

  • What are the major changes? Apply existing validation helpers to condition and loop inputs, question settings, tool approval and automatic sending settings, agent external-loop conditions, HTTP timeouts, message selection, and variable-scope selection. Validate tool automatic-send settings before dispatch and preserve each invocation's evaluated setting across responses, approval, and checkpoint restoration, including replacement MCP approvals. Evaluate function automatic-send settings only for result processing, so restored approval denials complete without evaluating an unrelated setting. Register function automatic-send checkpoint state in the source-generated JSON context and cover real JSON save/resume with fresh workflows. Validate restored loop inputs, update the checked-in condition and all three foreach workflow fixtures, compile those loop fixtures for behavioral regression tests, and clarify the expression-evaluation contract.
  • What is the impact of these changes? Invalid decision inputs raise DeclarativeActionException instead of being consumed without validation; invalid automatic-send settings do not dispatch tool requests. Pending invocations retain their original automatic-send behavior even when workflow state changes, including JSON checkpoints with reflection-based serialization disabled. Older approval denials clear pending state and record the denial; approved older requests still validate settings before invoking a function. Non-sensitive expressions, literal defaults, and metadata-preserving assignments keep their existing behavior. Add focused executor, checkpoint, generated-loop, and end-to-end regression tests, and keep configuration-loading tests focused on loading and assignment.
  • What do you want reviewers to focus on? Consistency with the existing input-validation helpers, per-request response correlation, backward-compatible and source-generated JSON checkpoint restoration, default-value behavior, generated-loop parity, and ensuring invalid conditions do not execute either branch.

Validation from dotnet:

  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore --filter-method '*RejectsSensitive*': failed as expected before the implementation fix (23 regression cases).
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore --filter-method '*ClearVariablesRejectsSensitiveScopeAsync': failed as expected before the corresponding implementation fix (1 regression case).
  • dotnet build src\Microsoft.Agents.AI.Workflows.Declarative\Microsoft.Agents.AI.Workflows.Declarative.csproj --no-restore --tl:off: passed for all five target frameworks, with zero warnings and errors.
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore --filter-class '*InvokeMcpToolExecutorTest': failed before the reapproval repair (6 regression cases); passed afterward (88 tests).
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore --filter-class '*ForeachExecutorTest': failed before the remaining fixture repairs (2 restore regression cases); passed afterward (26 tests).
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore: failed before the initial review repairs (16 behavior regressions and 1 test-fixture failure); passed after all repairs and formatting (1,088 tests).
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore -p:JsonSerializerIsReflectionEnabledByDefault=false --filter-method '*AutoSendSnapshotSurvivesJsonCheckpointAsync' --no-progress: failed before the JSON registration repair (4 cases with missing dictionary type information); passed afterward (4 tests).
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore --filter-method '*LegacyApprovalResponseValidatesAutoSendOnlyWhenApprovedAsync' --no-progress: failed before the denial repair (2 denial cases); passed afterward (4 denial/approved validation cases).
  • dotnet test --project tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests -f net10.0 --no-restore --no-progress: passed after all repairs and formatting (1,096 tests).
  • dotnet format src\Microsoft.Agents.AI.Workflows.Declarative\Microsoft.Agents.AI.Workflows.Declarative.csproj --no-restore: passed.
  • dotnet format tests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests\Microsoft.Agents.AI.Workflows.Declarative.UnitTests.csproj --no-restore: passed.

Related Issue

N/A - maintainer-requested bugfix tracked internally; no public issue was opened. No competing open PR for this fix was found.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: GitHub Copilot assisted with implementation, regression tests, documentation, and this PR description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Apply existing input validation to workflow decisions and restored loop inputs. Add regression coverage and clarify expression evaluation usage.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: bd63c138-6c7d-4cff-b97e-a21fd7206604
Copilot AI balanced review requested due to automatic review settings October 13, 2026 18:11
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs .NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows labels Oct 13, 2026
@github-actions github-actions Bot changed the title fix(dotnet): validate declarative control-flow inputs .NET: fix(dotnet): validate declarative control-flow inputs Oct 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The implementation and regression coverage are sound; only a non-blocking misplaced test summary remains.

1 open finding
What changed in this PR

Standardizes sensitivity validation for declarative workflow control-flow inputs.

Changes:

  • Rejects sensitive values used in decisions and control settings.
  • Validates restored loop state and clarifies evaluation guidance.
  • Adds focused executor and end-to-end regression coverage.
File Description
Workflows/​ConditionElse.cs Uses sensitivity-validating evaluation.
Workflows/​Condition.cs Updates generated condition evaluation.
RetrieveConversationMessagesExecutorTest.cs Tests message selection validation.
QuestionExecutorTest.cs Tests question-setting validation.
InvokeMcpToolExecutorTest.cs Tests MCP control settings.
InvokeFunctionToolExecutorTest.cs Tests function-tool control settings.
InvokeAzureAgentExecutorTest.cs Tests agent control settings.
HttpRequestExecutorTest.cs Tests timeout validation.
ForeachExecutorTest.cs Tests loop and checkpoint validation.
ConditionGroupExecutorTest.cs Tests sensitive conditions.
ClearAllVariablesExecutorTest.cs Tests scope validation.
DeclarativeWorkflowTest.cs Adds end-to-end condition regression coverage.
README.md Documents control-flow validation.
RetrieveConversationMessagesExecutor.cs Validates limit and sort order.
QuestionExecutor.cs Validates prompting and retry settings.
InvokeMcpToolExecutor.cs Validates approval and auto-send settings.
InvokeFunctionToolExecutor.cs Validates approval and auto-send settings.
InvokeAzureAgentExecutor.cs Validates agent control settings.
HttpRequestExecutor.cs Validates request timeout.
ForeachExecutor.cs Validates current and restored loop items.
ConditionGroupExecutor.cs Validates branch conditions.
ClearAllVariablesExecutor.cs Validates variable-scope selection.
IWorkflowContextExtensions.cs Clarifies sensitivity handling contract.

🧠 Review effort: Balanced


💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): 6f46cb8f2295
Model: gpt-5.6-sol

Overview

The review found 3 verified inline finding(s).

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
3 verified findings remained after source verification (2 high, 1 medium) across 3 files. Details are attached to the affected lines below.

Affected areas: dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/ForeachExecutor.cs, dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs, dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeMcpToolExecutor.cs

@github-code-quality

github-code-quality Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage overview

Languages: C#

C# / code-coverage/dotnet

main 4509a61 fix/declarative-cont... d60ac32 +/-
86% 86% 0%
View coverage of the 6 most impacted files.
File main 4509a61 fix/declarative-cont... d60ac32 +/-
/home/runner/wo...SessionStore.cs 100% 53% -47%
/home/runner/wo...ToolExecutor.cs 97% 97% 0%
/home/runner/wo...agesExecutor.cs 100% 100% 0%
/home/runner/wo...ToolExecutor.cs 96% 99% +3%
/home/runner/wo...ueExtensions.cs 17% 31% +14%
/home/runner/wo...tionExecutor.cs 0% 36% +36%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.


Updated October 15, 2026 11:35 UTC

Retain automatic-send settings across matching responses and checkpoint restoration, and align checked-in loop validation.

Co-authored-by: Copilot <[email protected]>
Copilot-Session: bd63c138-6c7d-4cff-b97e-a21fd7206604

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

MCP reapproval reevaluates and loses the original automatic-send snapshot after checkpoint restoration.

1 open finding
1 resolved since last review

🧠 Review effort: Balanced

Co-authored-by: Copilot <[email protected]>
Copilot-Session: bd63c138-6c7d-4cff-b97e-a21fd7206604

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Equivalent generated loop baselines remain inconsistent with the new sensitivity-validation contract.

0 open findings

1 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Low severity Update stale generated foreach fixtures for sensitivity parity

dotnet/​tests/​Microsoft.Agents.AI.Workflows.Declarative.UnitTests/​Workflows/​LoopEach.cs:79

Equivalent generated foreach fixtures are still stale: Workflows/LoopBreak.cs:75-91,132-146 and Workflows/LoopContinue.cs:75-91,132-146 retain this same loop implementation without either sensitivity check. Since these files are checked-in generated baselines, equivalent foreach workflows now encode different validation contracts and the claimed generated-loop parity is incomplete. Regenerate/update all foreach baselines (and the generating template, if maintained here), not only LoopEach.cs.

🧠 Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The broad control-flow and backward-compatible checkpoint changes warrant final human validation despite strong regression coverage.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@baywet
Vincent Biret (baywet) added this pull request to the merge queue Oct 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 15, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Mixed legacy responses can use another invocation’s automatic-send setting and bypass required validation.

1 open finding

🧠 Review effort: Balanced

Refactor result handling to simplify auto-send logic.

Co-authored-by: Copilot Autofix powered by AI <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Security-sensitive approval handling and backward-compatible checkpoint restoration warrant final human review.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@baywet
Vincent Biret (baywet) added this pull request to the merge queue Oct 15, 2026
Merged via the queue into main with commit deecbcb Oct 15, 2026
36 checks passed
@baywet
Vincent Biret (baywet) deleted the fix/declarative-control-flow-validation branch October 15, 2026 18:24

This branch was previously deployed

2 inactive deployments
github-app-auth — d60ac328 Deployed Oct 15, 2026 by baywet via add_label #25436
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs .NET Usage: [Issues, PRs], Target: .Net workflows Usage: [Issues, PRs], Target: Workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants