feat(uipath-maestro-flow): add child simulation docs and skill test - #2965
Conversation
Add --parent flag docs to the evaluate capability for simulating individual tools inside agent nodes. A single command is enough — the parent simulation is auto-created if it does not exist. Skill changes: - CAPABILITY.md: add child simulation to "When to use" and "Common tasks" - commands-reference.md: add --parent to simulation add/list/remove flag tables, examples, and output codes - eval-sets-guide.md: add "Child Simulations" section with usage examples Skill test: - child_simulation_crud.yaml: full lifecycle test (add Static + Llm child, list, remove) with auto-created parent - check_child_simulation_crud.py: verifier for persisted eval-set JSON Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Claude finished @AAgnihotry's task in 3m 43s —— View job PR Review: feat(uipath-maestro-flow): add child simulation docs and skill test
SummaryThis PR adds documentation for the Change-by-Change Review1.
|
| Area | Status | Notes |
|---|---|---|
| Frontmatter | OK | Not modified — existing frontmatter unchanged |
| E2E Tests | OK | Smoke test added; this PR extends an existing skill, not a new one |
| Skill Body | OK | Three reference docs updated consistently |
| References & Assets | OK | All links verified, anchors resolve, no orphaned files |
| Repo Hygiene | OK | No secrets, no cross-skill refs, changes scoped to one skill |
Issues for Manual Review
- CLI flag accuracy: The
--parentflag behavior (auto-creating parent with typeagentand strategyLlm,--component-typedefaulting toNode,--output-schemanot auto-resolving for child sims) is documented per the companion CLI PR (UiPath/cli#3923). Reviewers with CLI access should verify these defaults match the actual implementation. - Output code names:
FlowEvalChildSimulationAdd/List/Removeshould be confirmed against the CLI's actual JSON output.
Conclusion
Clean PR. Documentation is well-structured, consistent with existing simulation docs, and follows repo conventions. The test task is thorough with a good Python verifier. No blocking issues found — approve once the passing-run claim is added.
|
Claude finished @AAgnihotry's task in 2m 58s —— View job Coder-eval task lint (advisory)1 task YAML changed; verdicts: 0 Critical, 1 High, 0 Medium, 1 Low, 0 OK. Rubric: .claude/commands/lint-task.md. This check is advisory and never blocks merge. Evidence of passing run❌ High — PR body does not claim the changed/added tasks have been run and passed. The "Test plan" section contains unchecked boxes (
Per-task lint
|
Remove explicit --parent auto-creation hints from the test prompt so the agent must learn this behavior from the skill docs instead of the prompt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rebase onto main (#3016) The rebase of campaign/same-ground-expansion onto main (0afe5c1) brought in two uipath-maestro-flow tasks that the alignment sweep never saw, and the permanent corpus guard (test_same_ground_corpus.py) went red on four contracts: - evaluate/child_simulation/child_simulation_crud.yaml (#2965, today) gates on `uip solution init` / `uip maestro flow init` telemetry — v1-only authoring grammar. - ixp/e2e_03_project_creation_handoff (#2809, inherited on the previous rebase) gates on two skill_triggered criteria, tells the agent "do not run `uip maestro flow debug`", and its grader imported `flow_check` bare from a `../../_shared` sys.path entry. Carry the two tasks in the temporary allowlists, named with their upstream PR, so the guard stays exact (no silent widening) until each gets its own alignment pass. Fix the one contract that has no allowlist by design: handoff.py now uses the package-qualified `from _shared.flow_check import …` form every converted grader uses, which also resolves in coder-eval's isolated task mount where `_shared` is co-located rather than a sibling of `$TASK_DIR/..`. Verification: `pytest tests/tasks/uipath-maestro-flow/` 1140 passed (was 4 failed); e2e_03's own test_handoff.py 51 passed; handoff.py imports standalone. 🤖 Generated with Claude Code Claude-Session: https://claude.ai/code/session_01VwTyMj73xjaUbCMsADvTSr Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…rebase onto main (#3016) The rebase of campaign/same-ground-expansion onto main (0afe5c1) brought in two uipath-maestro-flow tasks that the alignment sweep never saw, and the permanent corpus guard (test_same_ground_corpus.py) went red on four contracts: - evaluate/child_simulation/child_simulation_crud.yaml (#2965, today) gates on `uip solution init` / `uip maestro flow init` telemetry — v1-only authoring grammar. - ixp/e2e_03_project_creation_handoff (#2809, inherited on the previous rebase) gates on two skill_triggered criteria, tells the agent "do not run `uip maestro flow debug`", and its grader imported `flow_check` bare from a `../../_shared` sys.path entry. Carry the two tasks in the temporary allowlists, named with their upstream PR, so the guard stays exact (no silent widening) until each gets its own alignment pass. Fix the one contract that has no allowlist by design: handoff.py now uses the package-qualified `from _shared.flow_check import …` form every converted grader uses, which also resolves in coder-eval's isolated task mount where `_shared` is co-located rather than a sibling of `$TASK_DIR/..`. Verification: `pytest tests/tasks/uipath-maestro-flow/` 1140 passed (was 4 failed); e2e_03's own test_handoff.py 51 passed; handoff.py imports standalone. 🤖 Generated with Claude Code Claude-Session: https://claude.ai/code/session_01VwTyMj73xjaUbCMsADvTSr Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…rebase onto main (#3016) The rebase of campaign/same-ground-expansion onto main (0afe5c1) brought in two uipath-maestro-flow tasks that the alignment sweep never saw, and the permanent corpus guard (test_same_ground_corpus.py) went red on four contracts: - evaluate/child_simulation/child_simulation_crud.yaml (#2965, today) gates on `uip solution init` / `uip maestro flow init` telemetry — v1-only authoring grammar. - ixp/e2e_03_project_creation_handoff (#2809, inherited on the previous rebase) gates on two skill_triggered criteria, tells the agent "do not run `uip maestro flow debug`", and its grader imported `flow_check` bare from a `../../_shared` sys.path entry. Carry the two tasks in the temporary allowlists, named with their upstream PR, so the guard stays exact (no silent widening) until each gets its own alignment pass. Fix the one contract that has no allowlist by design: handoff.py now uses the package-qualified `from _shared.flow_check import …` form every converted grader uses, which also resolves in coder-eval's isolated task mount where `_shared` is co-located rather than a sibling of `$TASK_DIR/..`. Verification: `pytest tests/tasks/uipath-maestro-flow/` 1140 passed (was 4 failed); e2e_03's own test_handoff.py 51 passed; handoff.py imports standalone. 🤖 Generated with Claude Code Claude-Session: https://claude.ai/code/session_01VwTyMj73xjaUbCMsADvTSr Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…rebase onto main (#3016) The rebase of campaign/same-ground-expansion onto main (0afe5c1) brought in two uipath-maestro-flow tasks that the alignment sweep never saw, and the permanent corpus guard (test_same_ground_corpus.py) went red on four contracts: - evaluate/child_simulation/child_simulation_crud.yaml (#2965, today) gates on `uip solution init` / `uip maestro flow init` telemetry — v1-only authoring grammar. - ixp/e2e_03_project_creation_handoff (#2809, inherited on the previous rebase) gates on two skill_triggered criteria, tells the agent "do not run `uip maestro flow debug`", and its grader imported `flow_check` bare from a `../../_shared` sys.path entry. Carry the two tasks in the temporary allowlists, named with their upstream PR, so the guard stays exact (no silent widening) until each gets its own alignment pass. Fix the one contract that has no allowlist by design: handoff.py now uses the package-qualified `from _shared.flow_check import …` form every converted grader uses, which also resolves in coder-eval's isolated task mount where `_shared` is co-located rather than a sibling of `$TASK_DIR/..`. Verification: `pytest tests/tasks/uipath-maestro-flow/` 1140 passed (was 4 failed); e2e_03's own test_handoff.py 51 passed; handoff.py imports standalone. 🤖 Generated with Claude Code Claude-Session: https://claude.ai/code/session_01VwTyMj73xjaUbCMsADvTSr Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* test(maestro-flow): add arm-neutral flow discovery (#2745) 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): align loop-neutral task batch (#2748) Apply the ratified same-ground alignment recipe to the 31 Batch 1 tasks and preserve their criterion intent and weights. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): align HITL and interactive task batch (#2749) Apply the ratified same-ground recipe to the 16-task HITL and interactive batch. Preserve criterion intent and weights while replacing loop-coupled paths and telemetry with shared artifact checks. All required CI checks pass; the local paired run remains blocked by the recorded expired UiPath refresh token. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): align bindings and connector features (#2750) Apply the ratified same-ground recipe to the 26-task bindings and connector-features batch. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): align IxP and context-grounding tasks (#2751) Apply the same-ground measurement contract to the nine-task Batch 4 roster while preserving criterion weights and semantic intent. Route Flow discovery through shared helpers, make loop-specific telemetry report-only, remove authoring-loop prompt coaching, and cover the no-Flow CLI path. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): align connector trigger, e2e, edit, and evaluation tasks (#2752) Apply the ratified same-ground recipe to the exact Batch 5 roster while preserving task intent and criterion weights. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): fix phase 2 contract false negatives Accept equivalent SDK expression and inline quick-form representations, grade the Celsius result the prompt requests, normalize evaluator/report spelling, and name the managed fallback in the query-parameter prompt. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * style(maestro-flow): format alignment checks 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): accept legacy exact-match evaluators Recognize the low-code evaluator schema's category 0/type 1 form as the same exact-match outcome as the coded evaluatorTypeId form. Keep JSON similarity and other evaluator types rejected. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): tighten review edge cases Scope approve/reject detection to the HITL schema and use the same SHA-256 content identity as shared flow discovery. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): clarify trigger detail shape State the already-graded top-level filter requirement explicitly after two same-agent smoke rows nested the value under an outer descriptor. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): align GenerateSchema eval across loops Use shared outcome-based artifact discovery, make loop-specific describe telemetry advisory, and validate the persisted Flow independently. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix(evals): make shared grader imports sandbox-safe Use package-qualified imports so co-located _shared helpers resolve in isolated coder-eval task mounts, and guard the contract across Flow graders. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix(maestro-flow): remediate live and preview eval failures (#2821) * fix(evals): anchor shared grader staging to its checkout 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(evals): provision the preview Flow SDK offline 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(evals): scope shared staging to the selected suite 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-flow): allow dynamic validation latency 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(evals): pin preview to remediated Flow SDK 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(preview): preserve operation-specific schema parents 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(flow): preserve requested checkpoints and topology Capture requested mutation snapshots before optional cleanup steps, and allow validate-only IxP graphs to mark missing extractors with placeholders. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(evals): pin canonical preview guidance Advance the preview build context to the Flow SDK commit that owns the remediated connector and IxP guidance. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(evals): harden Jira seed envelope parsing Retry only explicitly transient folder lookups and surface a redacted failure envelope instead of an opaque missing-Data traceback. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(evals): bake released Flow SDK into shared image (#2841) * test(maestro-flow): align Data Fabric same-ground tasks (#2846) Align the post-rebase Data Fabric tasks with the campaign same-ground contract and read canonical connector query parameters in artifact verifiers. Verification: GitHub smoke run 33045213813 passed 8/8 tasks. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(evals): point the Flow v2 preview experiment at the shared image #2841 moved @uipath/flow-sdk and the connector registry into the shared image and taught nightly.yaml to stage them, but flow-v2-preview.yaml was left on the old contract: a skills-codex:latest image nothing builds any more, and an npmrc pre_run for an in-sandbox npm install the image now makes unnecessary. Point it at skills-image:latest and stage the baked SDK the way nightly.yaml does, so both arms of the comparison get the same SDK from the same place. Staging is unconditional here rather than gated on MAESTRO_FLOW_SDK_SETUP: a preview run always authors through the SDK. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(maestro-flow): restore campaign CI after rebase (#2896) Remove duplicated generated rules, align validator tests with shared discovery, and keep same-ground voice tasks outcome-based. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-case): recognize V30 stage references (#2897) * fix(maestro-case): recognize V30 stage references 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-case): align V30 checker discovery Recognize plural V30 stage references across the corpus and select the substantive authored caseplan when packaging leaves a duplicate scaffold. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-case): make grading author-loop neutral (#2898) * fix(maestro-flow): restore campaign CI after rebase Remove duplicated generated rules, align validator tests with shared discovery, and keep same-ground voice tasks outcome-based. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-case): make skill telemetry advisory Grade functional Case behavior consistently across authoring loops and keep skill-invocation telemetry as diagnostics only. Add a corpus guard so new gating activation criteria cannot regress parity. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-case): remove author-loop grading assumptions 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(maestro-bpmn): accept message summary events (#2899) 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-bpmn): accept registry-native agent jobs (#2901) Align the live skill, bundled registry fallback, and checker with the runtime-authored Orchestrator.StartAgentJob shape emitted by the CLI registry while retaining the nested type contract for other nodes. Add focused checker coverage for both supported declarations. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * Accept the SDK default for optional Case tasks (#2902) Align the evaluator with the Case SDK contract: omitted isRequired and explicit false both mean non-required.\n\n🤖 Generated with Claude Code\nCo-Authored-By: [Claude](mailto:noreply@anthropic.com) * Accept SDK-authored generic BPMN activities (#2905) Fixes #2904 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * Make BPMN evals author-loop neutral (#2909) Accept equivalent live-project and SDK-authored BPMN layouts while preserving semantic assertions. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * Align Case evals across authoring loops (#2911) Accept equivalent Case defaults, layouts, and audit shapes while keeping semantic requirements intact. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): make artifact discovery author-loop neutral (#2913) Resolve one substantive Flow project across equivalent live and SDK authoring layouts while retaining ambiguity checks for genuinely distinct artifacts. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): remove remaining arm-specific checks (#2915) Normalize Flow validation and checker contracts across the live and SDK authoring loops, including offline connector tasks. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): accept equivalent connector artifacts (#2919) Teach the affected Flow checkers to recognize the equivalent live-authoring and SDK persistence forms while preserving negative controls. Fixes #2917 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): clarify task resource scope (#2920) State the tenant-wide connection scope and required Slack connector identity that the existing criteria grade. Fixes #2918 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * test(skills): stabilize npm publish dry runs 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): accept supported Slack lookup routes (#2945) Grade the resolved Slack channel outcome across both manual resource collections and the SDK lookup resolver, with a regression test for each route. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) * fix(maestro-flow): restore the routing tasks' loop-neutral scope clause The same-ground sweep (#2751) removed the whole "Important:" block from `ixp/routing.yaml` and `ixp/routing_negative.yaml`. Most of that block was loop coaching and belonged out (`--output json`, "validate at most once"), but one sentence was the task's own scope — "a skeleton whose nodes cover the steps is enough; leave a node unconfigured rather than leaving a step out" — and nothing replaced it. Every other task in the sweep kept a loop-neutral "Do NOT ask for approval… build in a single pass" line; the two routing YAMLs lost theirs and got nothing back. Without it the routing rows turned from a routing smoke into "build a working flow against live tenant connections", on an unchanged 25-turn budget. In adhoc-2026-09-01_06-35-33 (gpt-5.6-luna, both arms): - live-v1: `sf-update` and `stripe-http` ended their only turn asking the user a question ("Which Salesforce stage…?", "Which should I use?") — the skill's dropdown rule #5 in a headless run — and produced no artifact; 5 of the 8 negative rows that did pass ran into the 25-turn cap first. - SDK-v2: `sf-update` spent its budget chasing the tenant-specific Salesforce `update-record` schema (a real SDK `prepare` defect, fixed in flow-builder-sdk) and `teams-decision` hit the cap the same way. - The official baseline (`2026-09-01_04-16-00`, gpt-5.6-terra, skills main with the block) passed all 8 rows in 8-18 tool calls, leaving nodes unconfigured exactly as told. This restores the scope sentence in loop-neutral words: skeleton is enough, leave unconfigured rather than omit or ask, do not ask for approval or missing details, do not iterate to make it runnable. No CLI or SDK coaching, no debug/deploy instruction (the corpus test forbids it, and the budget already precludes debug). The campaign checker's stricter requirement that a `.flow` must exist (`flow_contains.py --absent-regex`, replacing a `! grep` that passed vacuously with no artifact) is kept — that was a checker bug on main, not something to restore. Limits are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G1JCRWy18Fgw4q8m5Lx6V6 * fix(eval-image): read the connector library location from the CLI, not from a snapshot layout it stopped writing The Dockerfile's registry step hard-coded the layout `uip maestro registry pull` used to produce: a snapshot under $UIP_MAESTRO_REGISTRY_HOME plus a `current.json` pointer. From @uipath/maestro-tool 1.202.0-dev.8461 (published 2026-09-01 18:13Z, carrying cli#3823) the command delegates to the Flow SDK, which caches the library under ~/.uipath/cache/flow-sdk/library/<sha256>/ and writes no current.json — so every fresh `docker build` of this image has failed since that publish: jq: error: Could not open file /opt/preview-flow-sdk-assets/registry/current.json The nightly and ADO builds have not noticed yet only because they do not pass --no-cache: the `npm install @uipath/maestro-tool@dev` layer is keyed on the command string, not on what the floating tag resolves to, so they keep replaying the 08-27 layer. Any cache eviction reproduces the failure. Fix at the layer where the coupling lives: the image now asks the CLI where the library is (`uip maestro registry path --library-json | --sha`), keeps the old pointer as the source when a pinned older CLI still writes it, and then records the image's OWN provenance pointer at $UIP_MAESTRO_REGISTRY_HOME/ current.json (libraryHash + snapshotPath). The per-task stage-preview-sdk-workspace.sh and the run scripts read that one contract unchanged, whichever layout the installed CLI produced. Verified by running the step's shell against the new-layout host CLI: pointer written, asset links resolve, stage script reports the library hash. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G1JCRWy18Fgw4q8m5Lx6V6 * fix(maestro-flow): name the routing tasks' deliverable — the .flow artifact The restored scope clause said "a skeleton is enough" without saying what the skeleton IS. The two loops read that differently: for the live-v1 loop the skeleton is the `.flow` the CLI writes, so 8/8 rows passed; for the SDK loop the skeleton is `<Name>.flow.ts`, and 7/8 rows stopped there — "No runnable validation was performed", "left unset per scope" — so no `.flow` existed for the artifact check (local rerun 2026-09-01 19:12, preview arm 1/8). Name the outcome the checker grades, which both loops produce: the `.flow` file. Still loop-neutral — no command, no mechanism — and the corpus tests stay green. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G1JCRWy18Fgw4q8m5Lx6V6 * fix(flow-check): classify a Completed debug with unreadable outputs as INFRA, keep the CLI stderr (#2967) `run_debug` graded whatever `uip maestro flow debug` returned on exit 0. When the CLI's post-completion fetch of the output variables failed, the CLI (before UiPath/cli#3929) printed `Result: Success` with no `variables` key at all and the failure reason only on stderr — which `run_debug` discarded on a zero exit. `assert_outputs_contain` then reported "Outputs missing …; present=[]" and the task was graded as a flow defect. Observed on coder-eval `skill-flow-move-node` v2 on 2026-08-31 and 2026-09-01: every element Completed, `Outputs: []`, score 0.375. The same artifact debugged 7/7 with outputs from a host and from inside the eval image. - A Completed payload whose `Data` has no `variables` key, or carries the new `variablesError`, is now classified as "outputs UNREADABLE" — the debug is retried once (its own 2-attempt budget, independent of the 3 attempts for 5xx/RetryLater), and if it persists the check fails with an INFRA message, never "Outputs missing". The condition is key-absent, not empty: a flow that declares no outputs still returns `variables` with an empty `globals` map. - The CLI's stderr is kept for every attempt and printed (tail) in the FLOW_DEBUG_RAW_CAPTURE dump, so the next occurrence self-explains. Tests: 7 new (retry-then-grade, variablesError, persistent → INFRA with capture, present-but-empty not retried, budgets independent, classifier table, stderr in capture). Suite: 340 passed. Rebase note (2026-09-02, onto main 88d10d7): re-applied over main's #2960 (`run_debug` deadline/budget loop). The unreadable-outputs retry now extends `max_attempts` by one instead of assuming a third loop iteration, and still honours the deadline. Main's new budget guard (`test_criterion_budgets.py`) priced only `$TASK_DIR/...` commands; the campaign addresses checkers as `$SKILLS_REPO_PATH/tests/tasks/uipath-maestro-flow/...`, so the guard now resolves both forms (686 pass, every campaign criterion clears its budget). Suite after rebase: 723 passed. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_0193r8XwXyqZqZwbBXXuwiHA Claude-Session: https://claude.ai/code/session_01SMAwQ1iQQSUUPi3oatMqgG Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(flow-check): name an unconfigured connector node instead of "no create-entity-record" (#2972) * fix(flow-check): name an unconfigured connector node instead of "no create-entity-record" skill-flow-datafabric-smoke-file-activities, SDK arm, 2026-09-01: the agent placed `create-entity-record` through `rawNode`, so the node existed but carried its inputs flat with no `inputs.detail`. The checker reads entity/body/connection from `detail` (that is what the platform reads), skipped the node, and said "no create-entity-record on FlowCodeEvalEntity" — which reads as "the agent forgot the step". It did not; the step can never run. The verdict is unchanged (same nodes pass, same nodes fail — verified on the 09-01 v1 pass, the 09-01 v2 fail and the 08-31 22:43 v2 fail artifacts). The FAIL line now says where entityName is expected and lists connector nodes that have no `inputs.detail`, so the next reader lands on the enabling defect (flow-builder-sdk#663 refuses that shape at compile) instead of the prompt. Tests: 3 new (configured pass, raw-unconfigured fail + message, nested-body fail); pytest tests/tasks/uipath-maestro-flow → 343 passed; check-task-driver OK. Measurement contract: no prompt, criterion, weight or run_limits change. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMAwQ1iQQSUUPi3oatMqgG * fix(flow-check): render the unconfigured-node list without Python repr brackets (review nit) 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SMAwQ1iQQSUUPi3oatMqgG --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(flow-check): carry the backend's incident details when a debug run faults (#2981) `flow debug` reports a fault as one line per incident — `[102003] Integration Services bad request (element createIssue)` — and defers the provider's message to `uip maestro flow debug-instance incidents <id>`. The criterion output never carried that message, so six identical `[102003]` failures of skill-flow-e2e-escalation-jira-ticket across three arms and two weeks (08-19 → 09-01) read as an opaque IS error. The instance still had the answer on 09-02: `errors - {reporter=Specify a valid value for Reporter}` — the flow had bound the sender's e-mail into `fields.reporter.id`, an Atlassian account-id slot. run_debug now fetches the incidents for a faulted instance (exit≠0 with an instanceId, or exit 0 with finalStatus≠Completed) and appends `element= code= message: ErrorDetails` lines to the failure text. Best-effort, 60 s cap, never masks the original failure; grading is unchanged. RCA: workspaces/reports/2026-09-02-maestro-flow-escalation-jira-ticket/rca-escalation-jira-ticket.md 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_01TkcZFmSDDFpBghDWatA9gv Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(jira-teardown): confirm the irreversible delete — every Jira e2e teardown since 08-19 leaked its ticket (#2983) `uip is resources run delete` never prompts and refuses without `--yes` ("Confirmation required: this will delete resource 'issue' and cannot be undone. Re-run with --yes to confirm."). The five task-local `jira_is.py` helpers (escalation_jira_ticket, jira_create_issue, jira_get_issue, jira_lifecycle, jira_search_triage) called it without the flag, so every teardown in the 08-19 → 09-01 run archive printed `WARN: could NOT confirm deletion of CE-…` (escalation) or silently returned (the others), and the CE project accumulated the tickets: CE-1150 → CE-1256 are ALL eval-created (search-triage, lifecycle, flow e2e, ESC-JIRA), none deleted. The helper's refusal-is-not-a-deletion logic was right; the invocation was missing one word. Verified on the host 09-02: with `--yes` the delete returns Success and an independent re-read of the key answers 404 (CE-1257, CE-1258 — this session's own reruns). Tests: jira_create_issue/test_jira_is.py +1 (the command carries --yes); escalation_jira_ticket/test_jira_is.py new, 3 cases (confirmed delete → True; "Confirmation required" Failure → False; structured 404 → True). pytest tests/tasks/uipath-maestro-flow/: 1073 passed. Historical leaks left for Tao (not deleted here): CE-1169, CE-1172, CE-1173, CE-1183, CE-1186, CE-1222, CE-1225, CE-1247, CE-1248 (ESC-JIRA-… summaries), plus the search-triage / lifecycle / jira-flow-e2e tickets in the same range. RCA: workspaces/reports/2026-09-02-maestro-flow-escalation-jira-ticket/rca-escalation-jira-ticket.md §6 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_01TkcZFmSDDFpBghDWatA9gv Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(eval-checker): discover the orchestrator-paths flow for validate instead of hardcoding the v1 solution path (#2986) `escalation_orchestrator_paths.yaml` was the only e2e task whose "validates without errors" criterion ran `uip maestro flow validate CustomerEscalationOrchestrator/CustomerEscalationOrchestrator/CustomerEscalationOrchestrator.flow` by literal path. The SDK loop's own SKILL.md scaffolds `uip solution init <Name>Sol`, so an agent following it emits `CustomerEscalationOrchestratorSol/CustomerEscalationOrchestrator/…flow` and the criterion fails "File not found" on a flow that is otherwise green — adhoc 2026-08-31 22:43 v2 scored 0.68: every seeded path case passed, validate 0.0. Two of the task's six archived v2 failures carry this signature (08-29: `…Solution/`, 08-31 22:43: `…Sol/`). Every sibling (escalation_slack_alert, escalation_jira_ticket, jira_*) already validates through `_shared/validate_flow.py`, which discovers the project's `.flow` files the same way the checker does. Same weight, threshold and timeout. Criterion edit only — the prompt (fenced by FORBIDDEN_PROMPT_EXCEPTIONS) is untouched. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_013cn8thdbhgRMqTehFhnAWW Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(flow-check): INTERIM — retry a debug once as a new import when Studio Web's Overwrite answers 400/1001 (UiPath/cli#3938) (#2990) Since 2026-09-02 (last known good 2026-09-01 07:30Z) Studio Web's `Solution/{id}/Overwrite` returns `400 {"code":"1001","message":"An argument had an invalid value."}` for a solution that EXISTS. `uip maestro flow debug` imports a project on its first run and writes the server id back into the `.uipx` (`updateSolutionFile`), so every later debug of the same project is an overwrite, and the CLI treats a non-404 Overwrite as fatal. Every multi-case checker therefore died at solution upload on case 2, in all three arms: orchestrator_paths (7 cases), escalation_slack_alert, billing_invoice_lookup, decision, wiki_pageviews, canary. Reproduced on the host with the current CLI and yesterday's image (1.202.0-dev.8414), and with `uip solution upload --force`; a fresh bundled SolutionId imports as new and Completes with a real Slack post — only overwrite is broken. The one earlier archived Overwrite 400 (2026-08-26) was code 20001, a content error, and still fails. `run_debug` now: on exactly `Overwrite failed (400)` + `"code":"1001"`, rotate the `.uipx` SolutionId to a fresh uuid4 and retry ONCE (its own allowance, inside the existing deadline; `debug_budget()` untouched). Prints an INTERIM line naming the issue, both ids, and after success the server id of the new solution and the orphaned previous ones — `cleanup_solutions.py` reads only the current id. Never fires on 20001, on 404, or on exit 0. Self-disabling: once Overwrite recovers the signature stops matching; delete the block then. Tests: +6 (rotation then import; rotate once only; 20001 untouched; no .uipx → plain failure; classifier table). test_flow_check + test_criterion_budgets: 830 passed. The full tree's 3 failures in test_same_ground_corpus are pre-existing on the campaign tip (new ixp tasks from main's rebase, not allowlisted). 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_013cn8thdbhgRMqTehFhnAWW Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(flow-check): close the .uipx read handle in the interim SolutionId rotation (#2990 review nit) (#2991) 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_013cn8thdbhgRMqTehFhnAWW Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(eval-prompt): name the graded flow artifact in local_crud (SmokeEval.flow) (#2992) The same-ground sweep (#2752) rewrote this prompt loop-neutrally and, with the layout coaching, dropped every mention of the graded artifact: main named `SmokeEval.flow` three times, the campaign prompt zero. The graded criterion is `flow_contains.py --flow-name SmokeEval`. On 2026-09-01 the SDK-arm agent named its solution, project and flow `Smoke` (the only explicit-name miss in 918 graded --flow-name criteria; 1 of 6 SDK-arm runs, 0 of 6 v1 runs, same prompt and model; reasoning hidden). One loop-neutral clause restores the anchor; no layout, CLI or SDK coaching. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) Claude-Session: https://claude.ai/code/session_01DjcoqnpHbNPvfCBsp3gB9V Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(eval-prompt): routing tasks say where the deliverable goes — the current working directory, not a parent (#3012) The v1 prompt had "Work inside the stated working directory — do NOT `cd` to a parent." The campaign sweep dropped it with the rest of the "Important:" block, and the 09-01 restoration of the scope clause brought back the artifact ("the `.flow` file") but not its location. On 2026-09-02 the live-skill (v1, luna) agent on `ixp-routing-negative/teams-decision` ran `uip solution init` one directory above its row sandbox, wrote a correct `TeamsDecisionSolution/TeamsDecision/TeamsDecision.flow` there, and the checker (cwd = the row sandbox) found no `.flow`: 0.00. Same class as `ixp-routing/forms-classify` on 08-24 (2 of 495 archived fanned rows). Loop-neutral wording, both routing YAMLs; no checker or run-limit change. Claude-Session: https://claude.ai/code/session_01JizSrmrTUbJdHz8xKt65ks Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * test(maestro-flow): keep the corpus guard exact after the 2026-09-02 rebase onto main (#3016) The rebase of campaign/same-ground-expansion onto main (0afe5c1) brought in two uipath-maestro-flow tasks that the alignment sweep never saw, and the permanent corpus guard (test_same_ground_corpus.py) went red on four contracts: - evaluate/child_simulation/child_simulation_crud.yaml (#2965, today) gates on `uip solution init` / `uip maestro flow init` telemetry — v1-only authoring grammar. - ixp/e2e_03_project_creation_handoff (#2809, inherited on the previous rebase) gates on two skill_triggered criteria, tells the agent "do not run `uip maestro flow debug`", and its grader imported `flow_check` bare from a `../../_shared` sys.path entry. Carry the two tasks in the temporary allowlists, named with their upstream PR, so the guard stays exact (no silent widening) until each gets its own alignment pass. Fix the one contract that has no allowlist by design: handoff.py now uses the package-qualified `from _shared.flow_check import …` form every converted grader uses, which also resolves in coder-eval's isolated task mount where `_shared` is co-located rather than a sibling of `$TASK_DIR/..`. Verification: `pytest tests/tasks/uipath-maestro-flow/` 1140 passed (was 4 failed); e2e_03's own test_handoff.py 51 passed; handoff.py imports standalone. 🤖 Generated with Claude Code Claude-Session: https://claude.ai/code/session_01VwTyMj73xjaUbCMsADvTSr Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(uipath-maestro-flow): route if/otherwise to a Decision, name the Decision's outputs, add the move-a-node recipe, refuse Merge after a Decision (#3024) Four one-row/one-sentence edits in the docs the failing v1 (luna) agents actually opened, from the 2026-09-02 v1-only batch RCA (skill-flow-decision, skill-flow-move-node): - greenfield.md "Select the node type" (opened by every decision run; the two failing runs never reached plugins/decision/*): a two-outcome "if … otherwise …" requirement is a core.logic.decision node, not a Script ternary. Terra's baseline already builds the Decision, so the sentence cannot steer it to a worse shape. - plugins/decision/impl.md: an "Outputs" section — the Decision has no `.output`; readers use `$vars.<id>.matchedCaseId` / `.matchedCase` (registry outputDefinition). Four v1 runs and one nightly wrote `$vars.<id>.output.matchedCaseId` (→ [300501]). Plus a Debug row for [400302] when the Decision's `expression` reads a node that runs after it (two v1 runs, after moving the Decision). - brownfield.md "Common edits": a "Move / reorder a node" row — re-point every `$vars.<node>` read in the moved node to a node that still runs before it. - plugins/merge/planning.md heuristics: joining ONE Decision's branches with a Merge hangs the run; wire both ports into the next node (validate refuses the shape since UiPath/cli#3930). .maintenance/check-all.sh: 78 files, 26 plugins, 13,442 lines, 0 violations. No prompt, checker, criterion, weight or run_limits change. Claude-Session: https://claude.ai/code/session_01ENT7zRXbZyvku1y9BNC9TH Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(flow-check): INTERIM Overwrite rotation also recognises the CLI's staged error envelope (UiPath/cli#3951) (#3026) The Studio Web Overwrite 400/1001 regression (UiPath/cli#3938) is met by the campaign checker with one SolutionId rotation + import-as-new retry. The detector matched only the legacy text `Overwrite failed (400): {"code":"1001",…}`. Since UiPath/cli#3951 (main 2026-09-02, `016231474`) the CLI reports the refusal against its stage: Message: "Failed during overwrite-solution: HTTP 400 on POST …/Overwrite — An argument had an invalid value." Context: {"HttpStatus": 400, "Stage": "overwrite-solution", "ErrorCode": "1001"} With an image whose CLI carries #3951, every second debug of a project failed with a plain `flow debug exit 1` and no rotation — seen 2026-09-03 on every multi-debug task of the batch-A rerun (decision, wiki_pageviews), BOTH arms. The nightly will hit the same as soon as its image picks up main ≥ #3951. `_is_overwrite_stuck` now also matches the staged envelope (stage `overwrite-solution` + code 1001, or HTTP 400 with the platform's "invalid value" wording when the code is absent); another stage or another code never rotates. Tests: 4 new parametrized cases + a run_debug-level rotation on the staged envelope; _shared suite 980 passed; check-task-driver OK. No prompt, criterion, weight or run_limits change. Delete with the rest of the INTERIM block when Overwrite works again. Claude-Session: https://claude.ai/code/session_01ENT7zRXbZyvku1y9BNC9TH Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(uipath-maestro-flow): put the if/otherwise → Decision routing where every greenfield read reaches it (#3027) #3024 added the routing sentence under "Select the node type" — line 241 of greenfield.md. The agents read the file with `sed -n '1,220p'` (34 of the 102 greenfield reads in the 09-02 run) or `'1,240p'` (17), and the first after-rerun of skill-flow-decision opened `1,220p`: the sentence was never in the model's context (verified 2026-09-03 from the transcript). One line in "Should you plan first?" (line 20, inside every observed read window) carries the same rule; the Step-3 paragraph stays for readers who get that far. .maintenance/check-all.sh green. No prompt, checker, criterion, weight or run_limits change. Claude-Session: https://claude.ai/code/session_01ENT7zRXbZyvku1y9BNC9TH Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(maestro-flow): address #2756 review (pagination gate, rotation cleanup, node_modules prune) (#3045) * Revert "chore(codeowners): preview uipath-maestro-case owned by @UiPath/maestro-cli-team" This reverts commit a786833. * fix(maestro-flow): address #2756 review — pagination gate, rotation cleanup sidecar, node_modules prune Review items from #2756 (rockymadden): - MAJOR 1 paginated_reference_lookup: the v1 paged-loop telemetry is advisory again at min_count 2; the gating criterion now requires "went past page 1" on a SUCCESSFUL command for either route (`… list … nextPage=` or `registry prepare … --resolve channel:`). Corpus test uses the real `npx flow-sdk registry prepare` form and adds negative cases. - MAJOR 3 Overwrite rotation: the rotated-away SolutionId is appended to a `.rotated-solution-ids` sidecar beside the `.uipx`; `cleanup_solutions.py` deletes those ids alongside the current one. Tests cover both halves. - MINOR 5 ceql_where / enhanced_enum prompts name neither `validate` nor `compile` (neither is graded there). - MINOR 7 drop the workspaces-only plan path from the 99 campaign headers; the three decisions stay inline. - MINOR 8 wiki_pageviews anchors operate.json to the discovered .bpmn's parent. - MINOR 9 cwd-rooted `**` scans in flow_check.py prune `node_modules` (the staged SDK symlink); test with a symlinked fixture tree. - MAJOR 2 SKILL.md prose casing `bpmn:ServiceTask` matches the template. - nits: stage_shared.sh guard compares realpaths; validate_flow.py dead branch removed (test updated); case_check.py long line wrapped; Dockerfile drops the unread FLOW_SDK_CONNECTORS_DIR plumbing (no consumer anywhere). - run-coder-eval.yml passes FLOW_SDK_VERSION from the repo variable (default `latest`). - Comment blocks over _OVERWRITE_STUCK / _VARIABLES_UNREADABLE trimmed; the evidence lives in UiPath/cli#3938 and #3929. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UauCCMBpJ7ws1meQwBfYSS --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * test(maestro-flow): pagination gate also accepts the uip maestro registry prepare form (#3047) The corpus test named the SDK resolver only as npx flow-sdk registry prepare; the CLI exposes the same resolver as uip maestro registry prepare (UiPath/cli#3969, top-level maestro registry, not maestro flow registry). Assert the yaml pattern matches that form too. Claude-Session: https://claude.ai/code/session_01UauCCMBpJ7ws1meQwBfYSS Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix(preview): make preview/ a real plugin root (skills/ + .claude-plugin) — v2 arm loaded zero skills (#3049) * fix(preview): make preview/ a real plugin root — skills/ + .claude-plugin/plugin.json Claude Code loads a local plugin only from <root>/skills/<name>/SKILL.md. preview/ had the three skill folders as direct children, so plugins.path=$SKILLS_REPO_PATH/preview loaded ZERO skills, silently, in every Flow v2 eval run since 08-20 (coder-eval only WARNs per task; 306 warnings in adhoc-2026-09-03_16-34-17). v2 agents fell back to node_modules/@uipath/flow-sdk/skill/SKILL.md by find / at median turn 10 (91/116), 25/116 never saw a skill doc, 9 Skill calls errored 'Unknown skill'. The Delegate SDK appends /skills to the plugin root and hit the same missing dir. - git mv preview/uipath-maestro-{flow,case,bpmn} -> preview/skills/ - add preview/.claude-plugin/plugin.json (name uipath-preview) so skills load as uipath-preview:uipath-maestro-* — nothing matches on the prefix (skill_triggered strips it; preview docs never mention uipath:) - rewrite the 44 sync-script targets, its test, the sync workflow, CODEOWNERS, verb-gate glob (preview/skills/*/), tests/README.md, yaml comment - plugins.path in flow-v2-preview.yaml / same-ground-ab.yaml is unchanged Verified: node --test sync test 2/2; sync script against local flow-builder-sdk writes into preview/skills/* and passes all snapshot gates; live `claude --plugin-dir preview` lists uipath-preview:uipath-maestro-{flow,case,bpmn} (the old layout listed nothing). Follow-up: coder_eval_uipath comparison.py:101 provenance read must add the skills/ segment. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JBM7mnPT6LzvHLCBtFXcek * fix(verb-gate): selective gate resolves preview/skills/<name>, not preview/skills Review finding on #3049: with the deeper layout the selective-gate sed cut the changed path at preview/skills. Both branches of the gate now name the skill dir. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JBM7mnPT6LzvHLCBtFXcek --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * fix: address remaining #2756 review feedback Pin the Flow SDK version in both eval images, align the bundled BPMN contracts with CLI main, and make timeout-sensitive pagination telemetry advisory. 🤖 Generated with Claude Code Co-Authored-By: [Claude](mailto:noreply@anthropic.com) --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Bai Li <bai.li@uipath.com>
Summary
--parentflag docs to the evaluate capability for simulating individual tools inside agent nodesWeb_Search,Send_Email) inside an agent node instead of the whole agentChanges
--parentto simulation add/list/remove flag tables, examples, and output codes (FlowEvalChildSimulationAdd/List/Remove)Skill test
Test plan
child_simulation_crudtask runs end-to-end🤖 Generated with Claude Code