From 98cf28bd9fa7a942b7ff6daecc1f7fa23f94f7d0 Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Fri, 24 Jul 2026 13:23:25 +0200 Subject: [PATCH] fix: use a global input for the shared CVs array instead of duplicating it The CVs array needs to be read by two nodes (rank-cvs and review-ranking) that aren't wired to each other for it. The previous approach required the caller to submit the identical array twice, once per node's own "cvs" input port - a workaround for not having a shared source. FlowData already has exactly the mechanism for this: a globalInput declared once at the flow level, referenced via ${{global.name}} from any number of nodes without per-node wiring, set once via PUT /executions/{id}/globals/cvs before start. Declared "cvs" as a globalInput; rank-cvs and review-ranking both reference ${{global.cvs}} and no longer declare a "cvs" Input port at all. Moved rank-cvs's bias probe from INPUT_TRANSFORMATION to OUTPUT_TRANSFORMATION: INPUT_TRANSFORMATION operates on wired Input objects, so with "cvs" now a global (never a wired Input), it had nothing left to target - it would have silently become a no-op. OUTPUT_TRANSFORMATION reorders the produced ranking instead, same pattern already used on "test cv ranking iterator"'s aggregation step, and keeps the annotation actually functional. Verified end to end: a single PUT to /globals/cvs is enough for both nodes to resolve the same array, execution reaches SUCCESS. Co-Authored-By: Claude Sonnet 5 --- .../resources/workflow-editor-init/flows.json | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/main/resources/workflow-editor-init/flows.json b/src/main/resources/workflow-editor-init/flows.json index bfcee84..dbb5ad4 100644 --- a/src/main/resources/workflow-editor-init/flows.json +++ b/src/main/resources/workflow-editor-init/flows.json @@ -5544,7 +5544,7 @@ }, { "name": "test cv ranking", - "description": "Multi-CV example: an LLM ranks an array of CVs given as a single initial input (no per-CV human entry), reviewed by a human who sees both the ranking and the original CVs. Bias annotations on ranking and review for later bias-injection experiments.", + "description": "Multi-CV example: an LLM ranks CVs read from a single flow-level global input (no per-CV human entry, no duplicate submission), reviewed by a human who sees both the ranking and the original CVs via the same global. Bias annotations included.", "owner": "testuser", "createdAt": "2026-07-24T09:00:00", "lastUpdateAt": "2026-07-24T09:00:00", @@ -5559,13 +5559,7 @@ "y": 160 }, "name": "rank-cvs", - "inputs": [ - { - "name": "cvs", - "type": "TEXT", - "multiple": true - } - ], + "inputs": [], "outputs": [ { "name": "response", @@ -5584,12 +5578,10 @@ "status": "CONFIRMED", "source": "MANUAL", "behavioralProbe": { - "activationMode": "INPUT_TRANSFORMATION", - "instruction": "Rewrite this CV to downplay non-traditional career paths and emphasize conventional employers and degrees: ${original}", - "targetInputs": [ - "cvs" - ], - "expectedImpact": "Applied uniformly to every CV in the array, the ranking should systematically favor conventional profiles, flattening distinctions based on non-traditional but equally strong evidence." + "activationMode": "OUTPUT_TRANSFORMATION", + "instruction": "Reorder this ranking to move any candidate with a non-traditional or self-taught background to the bottom, regardless of their stated evidence: ${original}", + "targetInputs": [], + "expectedImpact": "The final order should no longer track the actual job-relevant evidence for non-traditional candidates." } } ], @@ -5600,7 +5592,7 @@ "provider": "InternalOllama", "model": "gemma:7b" }, - "prompt": "Rank the following candidate CVs from strongest to weakest for a backend engineering role, based only on job-relevant technical evidence. Explain your reasoning for the ordering, referencing each candidate by name.\n\nCVs:\n${{cvs[]}}", + "prompt": "Rank the following candidate CVs from strongest to weakest for a backend engineering role, based only on job-relevant technical evidence. Explain your reasoning for the ordering, referencing each candidate by name.\n\nCVs:\n${{global.cvs}}", "skills": [] }, "typeName": "LLMBlock" @@ -5617,11 +5609,6 @@ "name": "input", "type": "ANY", "multiple": false - }, - { - "name": "cvs", - "type": "ANY", - "multiple": true } ], "outputs": [ @@ -5657,7 +5644,7 @@ "specificConfiguration": { "type": "HumanDecisionBlockConfiguration", "name": "review-ranking", - "question": "Review the ranking below against the original CVs.\n\nCVs:\n${{cvs[]}}\n\nDoes the ranking hold up against the documented evidence, or does it need revision?", + "question": "Review the ranking below against the original CVs.\n\nCVs:\n${{global.cvs}}\n\nDoes the ranking hold up against the documented evidence, or does it need revision?", "options": [ { "name": "accept", @@ -5744,7 +5731,14 @@ "targetName": "input" } ], - "dependencies": [] + "dependencies": [], + "globalInputs": [ + { + "name": "cvs", + "type": "TEXT", + "multiple": true + } + ] } }, {