Skip to content

fix(maestro-case): preserve same-name output bindings#2119

Open
song-zhao-25 wants to merge 1 commit into
mainfrom
fix/case-same-name-output-binding
Open

fix(maestro-case): preserve same-name output bindings#2119
song-zhao-25 wants to merge 1 commit into
mainfrom
fix/case-same-name-output-binding

Conversation

@song-zhao-25

@song-zhao-25 song-zhao-25 commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • preserve every explicit output-binding operator and both operands from SDD through tasks.md
  • dispatch output generation by operator so equal-name extracts such as greeting -> greeting retain reassign semantics and originalVar
  • define equal-name extraction as a controlled alias while still deduplicating independently minted output IDs
  • centralize the canonical output-row grammar in the shared I/O-binding planner; task plugins keep only a compact lossless-row placeholder and link to that contract
  • retain the inline-create boundary reminder so sibling resource schemas cannot replace Case binding rows
  • add a general io_binding e2e matrix using existing deterministic tenant resources; keep the original single_node/api-workflow test unchanged
  • make post-run solution cleanup non-interactive with the CLI-required --yes

Regression coverage

The new tests/tasks/uipath-maestro-case/io_binding/ eval covers:

  • literal, Case-variable, prior-task, and JavaScript-expression inputs
  • bare output auto-minting
  • renamed and nested extraction
  • literal, variable-copy, computed, and metadata assignments
  • the exact estimatedAge -> estimatedAge controlled-alias regression
  • global output-ID uniqueness, lossless tasks.md, tenant-resource reuse, solution shape, and Case debug execution telemetry

Verification

  • skill structure validation, task YAML parsing, Python grader compilation, runtime-payload casing guard, and git diff --check pass
  • all eight output-capable task templates route to the shared output-list contract; no task plugin retains a duplicated binding grammar
  • local coder-eval build produced a valid Case artifact; correcting the flattened grader's _shared import root allowed the official coder-eval re-evaluation of that exact preserved workspace to pass 2/2 criteria with score 1.000
  • Case validation passed, every structural I/O assertion passed, all five task executions completed in Case debug, and post-run solution cleanup succeeded
  • passing local result: tests/runs/2026-07-18_15-03-43
  • CI CLI verb gate and task-schema validation pass

CI note

maestro-case checker unit tests currently fails during pytest 9 collection before executing tests because two pre-existing files share the module name test_checkers.py (athena_cm_event and golden_rebuild/cm_golden_expense). The stacked base PR #2117 fails the same job.

Dependency

Stacked on #2117 because the same-name fix was developed against the inline-resource Case changes introduced there.

@song-zhao-25
song-zhao-25 force-pushed the fix/case-same-name-output-binding branch 8 times, most recently from 166b388 to 6f35558 Compare July 19, 2026 21:50
@song-zhao-25
song-zhao-25 force-pushed the test/case-inline-resource-e2e branch from 6d244f1 to 0df8009 Compare July 19, 2026 21:52
@song-zhao-25
song-zhao-25 force-pushed the fix/case-same-name-output-binding branch from 6f35558 to 919d7e7 Compare July 19, 2026 21:52
@song-zhao-25
song-zhao-25 changed the base branch from test/case-inline-resource-e2e to main July 20, 2026 03:01
@song-zhao-25
song-zhao-25 force-pushed the fix/case-same-name-output-binding branch from 919d7e7 to e6f73cf Compare July 20, 2026 03:02
@song-zhao-25
song-zhao-25 marked this pull request as ready for review July 20, 2026 03:05
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Claude finished @song-zhao-25's task in 2m 46s —— View job


Coder-eval task lint (advisory)

1 task YAML changed; verdict counts: 0 Critical, 0 High, 0 Medium, 0 Low, 1 OK.

Rubric: .claude/commands/lint-task.md. This check is advisory and never blocks merge.

Evidence of passing run

  • ✅ Author confirms passing run: "local coder-eval build produced a valid Case artifact; correcting the flattened grader's _shared import root allowed the official coder-eval re-evaluation of that exact preserved workspace to pass 2/2 criteria with score 1.000" and "passing local result: tests/runs/2026-07-18_15-03-43"

Per-task lint

tests/tasks/uipath-maestro-case/io_binding/io_binding.yaml — verdict: OK

No issues. The task is well-structured:

  • Self-report: criteria grade real CLI validation (uip maestro case validate) and a comprehensive Python grader against the actual caseplan.json + live debug run — no self-written reports.
  • Prompt: states the goal and constraints (build from SDD, preserve output rows, no inline API project). The estimatedAge -> estimatedAge mention is a ground-truth anchor for the regression under test, not procedure leakage.
  • Meaningful coverage: the Python grader (check_io_binding_case.py) validates resource bindings, input/output row shapes (bare, reassigned, custom, equal-name), task ordering, $xref resolution, global output-ID uniqueness, tasks.md preservation, variable contracts, solution shape, and all five debug executions reaching Completed/Successful.
  • Gameability: requires real tenant resource resolution, real uip maestro case validate, and real uip maestro case debug execution — cannot be faked.
  • Near-duplicate: materially distinct from single_node/api_workflow (single task, simple I/O) and entry_points_io (entry-points.json back-fill, not task-level bindings). No other sibling covers the full I/O binding matrix or same-name extraction regression.
  • CLI verb reachability: unable to run scripts/check-cli-verbs.py (execution not approved), but the only CLI command is uip maestro case validate — a well-established verb present in dozens of sibling tasks.
  • Sandbox: no env_packages, no redundant CLI install.
  • Run-limits: correctly placed under top-level run_limits:, not under agent:.

Within-PR duplicates

  • No duplicate clusters detected (only one task YAML added).

Conclusion

  • ✅ All changed tasks pass the rubric. Evidence of passing run confirmed.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Claude finished @song-zhao-25's task in 6m 48s —— View job


PR Review: fix(maestro-case): preserve same-name output bindings

  • Read review criteria and project conventions
  • Analyze full diff against origin/main
  • Read existing PR conversation
  • Review skill documentation changes
  • Review test changes
  • Check cross-skill references and link validity
  • Check for secrets/tokens/paths
  • Post final review

Summary

This PR fixes a regression where an equal-name output extraction like greeting -> greeting was incorrectly collapsed to bare greeting during planning, losing the reassignment semantics (originalVar) needed by the frontend. The fix centralizes the canonical output-row grammar in the shared I/O-binding planning plugin, updates all 8 task-type planning templates to point to that contract, and adds a comprehensive e2e test covering the full I/O binding matrix plus the specific equal-name regression. The cleanup script also gains --yes to prevent interactive prompts.

Change-by-Change Review

1. skills/uipath-maestro-case/SKILL.md (Critical Rule 6)

Severity: OK

Adds "and lossless" to the rule title plus a concise inline explanation of why greeting -> greeting differs from bare greeting. Well-scoped addition that strengthens the critical rule without bloating it.

2. skills/uipath-maestro-case/references/bindings-and-expressions.md

Severity: OK

Changes inline comma-separated outputs: decision, comments to list format (- outputs: / - decision / - comments). Consistent with the new one-item-per-row contract established in io-binding/planning.md.

3. skills/uipath-maestro-case/references/planning.md

Severity: OK

Two clean changes: (1) adds parenthetical "always read alongside the matching task plugin" to the I/O binding nav entry; (2) replaces the task-plugin-only instruction with an explicit dual-read directive ("Read both the task-type plugin and the shared I/O-binding plugin before writing the entry"). The new "Outputs are a lossless handoff" blockquote is well-placed after the field list and before the registry handoff. No duplication with the I/O-binding plugin — this is bridge content tying planning-level context to the shared contract.

4–9. references/plugins/tasks/{action,agent,api-workflow,case-management,process,rpa}/planning.md

Severity: OK

All six files receive the same pattern: (a) outputs field row changes from "Discovered via tasks describe" to "sdd.md task Outputs + resolved schema → Follow the shared I/O-binding output-list contract" with a link to io-binding/planning.md#canonical-tasksmd-output-list; (b) template code block changes from - outputs: <out1>, <out2> to the list form - outputs: / - <SDD output row, copied verbatim>. All links verified — the anchor target exists at io-binding/planning.md:60.

10–11. references/plugins/tasks/{connector-activity,connector-trigger}/planning.md

Severity: OK

These two files, which previously had no explicit output guidance, now get a one-line directive ("Populate outputs: using the shared I/O-binding output-list contract") plus the list-form template entries. Consistent treatment across all 8 task types.

12. references/plugins/tasks/create-inline-common.md

Severity: OK

Adds a "Projection is not normalization" blockquote reminding agents that the pinned builder contract (field names/types) does not replace the case binding rows — the original SDD operator and destination must be preserved in tasks.md. Good boundary reminder for the inline-resource creation flow.

13. references/plugins/variables/global-vars/impl-json.md (Uniqueness Rule)

Severity: OK

Three additions: (1) clarifies "independently minted" qualifier on uniqueness rule; (2) new "Reassigned-output collision" paragraph explaining that -> rows have independently minted source-side id that must be deduped; (3) new "Controlled alias" paragraph explaining the greeting -> greeting exception where id == var == originalVar and neither side gets a counter suffix. Both paragraphs include concrete examples. The prose is dense but technically precise and matches the impl-json dispatch rules.

14. references/plugins/variables/io-binding/impl-json.md

Severity: OK

The core fix: (1) the -> extract shape now explicitly allocates id from the global uniqueness pool and mirrors the allocated id into originalVar and target; (2) new "Equal-name extract edge case" paragraph after the shape list dispatches greeting -> greeting to the reassign shape with id == var == originalVar == target_var; (3) uniqueness cross-cutting rule clarifies var is never counter-suffixed on a -> row (it points to the existing case variable), while the source-side id is independently minted. Also adds a same-name annotation paragraph in the "Output Binding Shapes" subsection.

15. references/plugins/variables/io-binding/planning.md

Severity: OK

The centralizing change: (1) intro paragraph adds "The output operator is part of the data contract, not formatting: preserve ->, =, or bare form and both operands through tasks.md"; (2) new "Equal-name extract is still an extract" callout under the -> operator section; (3) new "Canonical tasks.md output list" subsection (the anchor target all 8 task plugins now link to) with a concrete example and the rule against comma-separated names; (4) new validation rule row in the table: "Any SDD Outputs row differs from its tasks.md item in operator or operand → ERROR".

16. tests/tasks/uipath-maestro-case/_shared/cleanup_solutions.py

Severity: OK

Three small fixes: (a) adds --yes flag to uip solution delete to prevent interactive prompts in CI; (b) updates the never policy log message to include --yes --output json; (c) falls back to r.stdout when r.stderr is empty for failure diagnostics. All correct and consistent.

17. tests/tasks/uipath-maestro-case/io_binding/check_io_binding_case.py

Severity: OK

424-line Python grader covering: (a) solution shape (no inline API projects, exactly one CaseManagement project); (b) resource bindings (Golden Expense echo and NameToAge each resolve to correct folder/resourceKey); (c) input bindings (literal, case-variable, cross-task, expression); (d) output bindings (bare auto-mint, reassigned ->, nested Error.Message ->, custom = literal/copy/computed/metadata); (e) the specific estimatedAge -> estimatedAge equal-name regression with equal_name=True flag; (f) task ordering via selected-tasks-completed entry conditions; (g) global output-ID uniqueness; (h) tasks.md lossless preservation (regex checks for all 8 output rows); (i) runtime debug execution telemetry. Well-structured with clear helper functions and descriptive failure messages.

18. tests/tasks/uipath-maestro-case/io_binding/fixtures/sdd.md

Severity: OK

212-line SDD fixture designing a single-stage case with 5 sequential api-workflow tasks against two existing tenant resources. Exercises all binding forms systematically: literal input, case-variable input, cross-task input, expression input, bare output, renamed extraction, nested extraction, literal/copy/computed/metadata assignments, and the estimatedAge -> estimatedAge regression. Section numbering jumps from 1.1 to 1.3 (missing 1.2) — this follows the SDD template convention where §1.2 (Stages Summary) is omitted for single-stage cases and is not an error.

19. tests/tasks/uipath-maestro-case/io_binding/io_binding.yaml

Severity: OK

Task YAML is well-structured: task_id: skill-case-io-binding-matrix follows the skill-<domain>-<capability> pattern; tags include uipath-maestro-case as first tag plus e2e, mode:build, and other valid tags; initial_prompt is goal-focused and not hand-holding; two run_command success criteria with appropriate weights (3.0 for validate, 6.0 for the full grader); no env_packages or @uipath/cli pin. post_run cleanup correctly wired.

What's Missing

Nothing identified. The PR is well-scoped: skill doc changes, test coverage, and cleanup fix all align with the bug fix.

Area Ratings

Area Status Notes
Frontmatter OK SKILL.md frontmatter unchanged; body change is scoped to Critical Rule 6
E2E Tests OK New io_binding e2e task covers the regression and the full binding matrix
Skill Body OK Critical Rule 6 updated with lossless semantics; no other body sections modified
References & Assets OK 15 reference files updated consistently; all links resolve; no content duplication beyond bridge sentences
Repo Hygiene OK CODEOWNERS entry exists; no secrets/paths; no cross-skill dependencies; --yes flag fix prevents interactive CI prompts

Issues for Manual Review

  • Domain accuracy of the equal-name controlled-alias rule. The PR defines that greeting -> greeting produces id == var == originalVar == "greeting" and skips the uniqueness counter. This is a semantic contract with the UiPath frontend (mutateRootVariables in VariableMutationUtils.ts). Verifying that this matches the actual FE behavior requires domain expertise beyond what the skill docs can validate.
  • Tenant resource availability. The e2e test depends on two specific tenant resources (CM-Golden-Expense-Reporting-106 and NameToAgeFixed2 in Shared/uipath-maestro-case/). If these are removed or renamed in the tenant, the test will fail. The PR body mentions "existing deterministic tenant resources" — confirming their availability is a manual check.
  • Stacked PR dependency. This PR is stacked on test(maestro-case): cover inline resource creation #2117. Merging out of order would break the base. Ensure test(maestro-case): cover inline resource creation #2117 merges first.

Conclusion

Clean PR. The documentation changes are internally consistent, well-centralized (single source of truth for the output-list grammar, 8 task plugins link to it), and the new e2e test provides thorough regression coverage for the equal-name binding fix plus the broader I/O binding matrix. The cleanup script fix (--yes flag) is a sensible CI hardening. No blocking issues found — approve.
|

@charlesliu9

Copy link
Copy Markdown
Contributor

is the test failure due to the issue fixed in another PR?

@song-zhao-25

song-zhao-25 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

@charlesliu9 yes

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Claude finished @song-zhao-25's task in 1m 18s —— View job


Coder-eval task lint (advisory)

1 task YAML changed; verdict counts: 0 Critical, 0 High, 0 Medium, 0 Low, 1 OK.

Rubric: .claude/commands/lint-task.md. This check is advisory and never blocks merge.

Evidence of passing run

  • ✅ Author confirms passing run: "local coder-eval build produced a valid Case artifact; correcting the flattened grader's _shared import root allowed the official coder-eval re-evaluation of that exact preserved workspace to pass 2/2 criteria with score 1.000" and "passing local result: tests/runs/2026-07-18_15-03-43"

Per-task lint

tests/tasks/uipath-maestro-case/io_binding/io_binding.yaml — verdict: OK

No issues. The task is well-structured:

  • Self-report: criteria grade real CLI validation (uip maestro case validate) and a comprehensive Python grader against the actual caseplan.json + live debug run — no self-written reports.
  • Prompt: states the goal and constraints (build from SDD, preserve output rows, no inline API project). The estimatedAge -> estimatedAge mention is a ground-truth anchor for the regression under test, not procedure leakage.
  • Meaningful coverage: the Python grader (check_io_binding_case.py) validates resource bindings, input/output row shapes (bare, reassigned, custom, equal-name), task ordering, $xref resolution, global output-ID uniqueness, tasks.md preservation, variable contracts, solution shape, and all five debug executions reaching Completed/Successful.
  • Gameability: requires real tenant resource resolution, real uip maestro case validate, and real uip maestro case debug execution — cannot be faked.
  • Near-duplicate: materially distinct from single_node/api_workflow (single task, simple I/O) and entry_points_io (entry-points.json back-fill, not task-level bindings). No other sibling covers the full I/O binding matrix or same-name extraction regression.
  • CLI verb reachability: unable to run scripts/check-cli-verbs.py (execution not approved), but the only CLI command is uip maestro case validate — a well-established verb present in dozens of sibling tasks.
  • Sandbox: no env_packages, no redundant CLI install.
  • Run-limits: correctly placed under top-level run_limits:, not under agent:.

Within-PR duplicates

  • No duplicate clusters detected (only one task YAML added).

Conclusion

  • ✅ All changed tasks pass the rubric. Evidence of passing run confirmed.

@song-zhao-25
song-zhao-25 force-pushed the fix/case-same-name-output-binding branch from e6f73cf to 1dd190a Compare July 20, 2026 16:20
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.

2 participants