fix(macros): fan-out aggregate re-tagging is per-scope, not top-level-only#87
Merged
Conversation
…-only The pass that re-tags Arg::Ref(fan_task) -> Arg::FanAgg (the kind-aware array-renormalizing expr) ran only over the top-level workflow body. An if-arm body is its own analysis scope (a synthesized sub-workflow), so a consumer of a fan_out binding INSIDE an arm silently got the plain parameter ref — exactly the double-encoding the FanAgg doc describes. Hook args had the same hole at every scope (they reuse arg_value, which handles FanAgg, but were never re-tagged). - Extract the pass into retag_fan_aggs(): covers task args AND hook args, returns the scope's fan task set; run it per scope — the top-level body in analyze_workflow and every arm body in synth_if. - Reject a fan_out binding as a workflow's (or value-if arm's) return with a spanned error: the outputs.parameters.return bubble is a plain valueFrom.parameter copy of the raw aggregate, whose elements are still individually JSON-encoded — the parent would read a double-encoded array. Consuming the aggregate in-workflow and returning that is the supported (and correct) shape. - New smoke bin + golden (pipeline_fanout_if) pins the in-arm consumer carrying the same nil-safe FanAgg re-norm expr as top level; two new UI fixtures pin the return rejections. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AzynLVNz1o2QJY14PkTGCq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The pass that re-tags
Arg::Ref(fan_task)→Arg::FanAgg(the kind-aware array-renormalizing expression) only ran over the top-level workflow body. Anif-arm body is its own analysis scope (a synthesized sub-workflow), so a consumer of afan_outbinding inside an arm silently got the plain parameter ref — exactly the double-encoding theFanAggdoc describes:Hook args had the same hole at every scope (they lower through
arg_value, which already handlesFanAgg, but were never re-tagged).How
retag_fan_aggs(): covers task args and hook args, returns the scope's fan task set. Run once per scope — the top-level body inanalyze_workflow, and every arm body insynth_if. Scope-local is correct by construction: aRefcan only name a task in its own node list (outer bindings enter an arm as captured inputs).fan_outbinding as a workflow's — or value-ifarm's — return value: theoutputs.parameters.returnbubble is a plainvalueFrom.parametercopy of the raw aggregate, whose elements are still individually JSON-encoded, so the parent would read a double-encoded array. Consuming the aggregate in-workflow and returning that is the supported shape. (An alternative is a kind-awarevalueFrom.expressionre-norm on the bubble — happy to explore that as a follow-up if you'd rather support the shape than reject it; rejecting seemed safer without live-cluster verification.)Testing
pipeline_fanout_if) pins the in-arm consumer carrying the same nil-safeFanAggre-norm expr as top level (composes with the v3.6 nil-safe lookup from 7fd2d88).cargo test --workspace+ clippy clean. (The pre-existinghost_nested_in_macro.stderrnote-ordering drift on rustc 1.97 is untouched here; it's fixed on theclaude/cargo-athena-analysis-de968hbranch.)🤖 Generated with Claude Code
https://claude.ai/code/session_01AzynLVNz1o2QJY14PkTGCq
Generated by Claude Code